From b548e98d3417a81f5c0e14fb28506972728fd2e1 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Tue, 28 Apr 2026 11:50:15 +0800 Subject: [PATCH] Update TLS 1.3 --- include/gmssl/tls.h | 257 +++- src/tls.c | 19 +- src/tls12.c | 6 +- src/tls13.c | 3042 +++++++++++++++++++++++++----------------- src/tls_ext.c | 21 +- src/tls_ocsp.c | 4 +- src/tls_psk.c | 5 +- src/tls_sct.c | 10 + src/tls_sni.c | 2 +- tests/tls13test.c | 2 +- tools/tls13_client.c | 83 +- tools/tls13_server.c | 32 +- 12 files changed, 2182 insertions(+), 1301 deletions(-) diff --git a/include/gmssl/tls.h b/include/gmssl/tls.h index f5b0b0e8..0032889f 100644 --- a/include/gmssl/tls.h +++ b/include/gmssl/tls.h @@ -744,7 +744,7 @@ typedef struct { uint8_t cert_chains[8192]; size_t cert_chains_len; size_t cert_chains_cnt; // 这是一个多余的值,不应该存储多余的值 - size_t cert_chain_idx; +// size_t cert_chain_idx; // == 1 mean the first certificate uint8_t *certs; // 这里应该改为cert_chain,我们将certs表示为互相独立的证书 size_t certslen; @@ -770,12 +770,6 @@ typedef struct { size_t cacertslen; int verify_depth; - - - - - - // NewSessionTicket int new_session_ticket; int new_session_ticket_cnt; @@ -794,10 +788,12 @@ typedef struct { // server_name is connection only // 5. status_request + int status_request; // if send in ClientHello, CertificateRequest // list of (uint24array)CertificateEntry.extensions.status_request.response uint8_t status_request_ocsp_responses[512]; size_t status_request_ocsp_responses_len; + // 10. supported_gruops int supported_groups[32]; size_t supported_groups_cnt; @@ -808,7 +804,7 @@ typedef struct { // 18. signed_certificate_timestamp int signed_certificate_timestamp; - uint8_t signed_certificate_timestamp_lists[512]; + uint8_t signed_certificate_timestamp_lists[512]; // list of uint16array size_t signed_certificate_timestamp_lists_len; // 35. session_ticket @@ -832,6 +828,23 @@ typedef struct { // 46. psk_key_exchange_modes int psk_key_exchange_modes; + // 47. certificate_authorities + //int certificate_authorities; + uint8_t ca_names[512]; + size_t ca_names_len; + + // 48. oid_filters + // ClientHello, CertificateRequest中是否包含这个扩展 + const uint8_t *oid_filters; + size_t oid_filters_len; + + + // 49. post_handshake_auth + int post_handshake_auth; + + // 50. signature_algorithms_cert + int signature_algorithms_cert; // 我方是否在ClientHello, CertificateRequest 中包含这个扩展 + // 51. key_share size_t key_exchanges_cnt; @@ -839,7 +852,6 @@ typedef struct { - int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client); int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt); int tls_ctx_set_signature_algorithms(TLS_CTX *ctx, const int *sig_algs, size_t sig_algs_cnt); @@ -925,8 +937,6 @@ enum { typedef struct { int is_client; // 这个在CTX中应该是有的 - int quiet; - tls_socket_t sock; TLS_CTX *ctx; @@ -974,9 +984,20 @@ typedef struct { // 己方的证书链,指向TLS_CTX中的cert_chains const uint8_t *cert_chain; size_t cert_chain_len; - int cert_chain_idx; // 这样就指向了CTX中的密钥 + size_t cert_chain_idx; + + int sig_alg; // 这个算法是和cert_chain中的end_entity_cert的公钥绑定的,并且是从客户端的signature_algorithms中 + + + + + /* + 客户端和服务器端的签名算法是没有关系的 + 服务器和客户端都是在选择自己的证书链的同时确定了自己的签名算法 + 这个签名算法是通过CertificateVerify通知给对方的 + + */ - int sig_alg; uint8_t peer_cert_chain[TLS_MAX_CERTIFICATES_SIZE]; @@ -1025,8 +1046,6 @@ typedef struct { SM2_SIGN_CTX sign_ctx; TLS_CLIENT_VERIFY_CTX client_verify_ctx; - - // 所有这些命名为ecdh的都需要替换掉 uint16_t ecdh_named_curve; X509_KEY ecdh_keys[2]; @@ -1036,75 +1055,74 @@ typedef struct { size_t peer_ecdh_point_len; - - // CertificateRequest.signature_algorithms = - // common(ClientHello.signature_algorithms, ctx->signature_algorithms) - /* - int signature_algorithms[2]; - size_t signature_algorithms_cnt; - */ - - - // handshake messages + // HelloRetryRequest int hello_retry_request; + + // CertificateRequest int certificate_request; - //int new_session_ticket; + + // NewSessionTicket + int new_session_ticket; + int new_session_ticket_cnt; + const char *session_in; + const char *session_out; // KeyUpdate size_t client_data_size; size_t server_data_size; - // extensions + // Extensions // 0. server_name - // server_name is client only, server should not response server_name ext int server_name; + // ClientHello.server_name uint8_t host_name[256]; size_t host_name_len; + // EncryptedExtensions.server_name (emtpy) // 5. status_request int status_request; - // ClientHello.status_request set by app + // ClientHello.status_request const uint8_t *status_request_responder_id_list; size_t status_request_responder_id_list_len; const uint8_t *status_request_exts; size_t status_request_exts_len; - // ServerCertificate.CertificateEntry.status_request - // 在选择好证书之后,这些值应该指向ctx->status_request_ocsp_responses - // 但是有可能指针为空或者长度为0 - // 如果客户端发送了status_request,还需要进一步检查是否匹配,如果不匹配,需要设置为0 + // CertificateRequest.status_request (empty) + // Certificate.CertificateEntry.status_request const uint8_t *status_request_ocsp_response; size_t status_request_ocsp_response_len; - // 10. supported_gruops + // 10. supported_groups + // in ClientHello; EncryptedExtensions int supported_groups[32]; size_t supported_groups_cnt; // 13. signature_algorithms + // in ClientHello, CertificateRequest; int signature_algorithms[2]; size_t signature_algorithms_cnt; // 18. signed_certificate_timestamp int signed_certificate_timestamp; + // ClientHello.signed_certificate_timestamp (empty) + // CertificateRequest.signed_certificate_timestamp (empty) + // Certificate.CertificateEntry.signed_certificate_timestamp const uint8_t *signed_certificate_timestamp_list; size_t signed_certificate_timestamp_list_len; - // 35. session_ticket - // NewSessionTicket - int new_session_ticket; - int new_session_ticket_cnt; + // 35. session_ticket (TLS12_ONLY) // 41. pre_shared_key + // in ClientHello; ServerHello int pre_shared_key; - uint8_t psk_identities[512]; + uint8_t psk_identities[512]; // list of PskIdentity objects size_t psk_identities_len; int psk_cipher_suites[8]; size_t psk_cipher_suites_cnt; - uint8_t psk_keys[32 * 8]; + uint8_t psk_keys[32 * 8]; // uint8array size_t psk_keys_len; - - + // selected const uint8_t *psk_identity; size_t psk_identity_len; uint8_t psk[32]; // 这应该改为一个指针 @@ -1112,25 +1130,47 @@ typedef struct { int selected_psk_identity; - // session_ticket - const char *session_in; - const char *session_out; - int client_certificate_verify; // TLS1.2 TLCP需要这个 // 42. early_data + // in NewSessionTicket, ClientHello1; EncryptedExtensions int early_data; size_t max_early_data_size; uint8_t early_data_buf[8192]; + size_t early_data_offset; size_t early_data_len; + // 43. supported_versions + // in ClientHello; ServerHello, HelloRetryRequest + // not optional + // 44. cookie + // in HelloRetryRequest; ClientHello2 int cookie; uint8_t cookie_buf[256]; size_t cookie_len; + // 46. psk_key_exchange_modes + // in ClientHello; + + // 47. certificate_authorities + // in ClientHello, CertificateRequest; + int certificate_authorities; + + // 48. oid_filters + int oid_filters; + + // 49. post_handshake_auth + int post_handshake_auth; + // in ClientHello; + + // 50. signature_algorithms_cert + // in ClientHello, CertificateRequest; + int signature_algorithms_cert; + // 51. key_share + // in ClientHello; HelloRetryRequest, ServerHello int key_share; X509_KEY key_exchanges[2]; size_t key_exchanges_cnt; @@ -1358,7 +1398,8 @@ int tls13_send_new_session_ticket(TLS_CONNECT *conn); // tls13 client/server -int tls13_send_key_update(TLS_CONNECT *conn, int request_update); +int tls13_send_client_key_update(TLS_CONNECT *conn, int request_update); +int tls13_send_server_key_update(TLS_CONNECT *conn, int request_update); int tls13_recv_key_update(TLS_CONNECT *conn); @@ -1384,6 +1425,8 @@ int tls12_do_connect(TLS_CONNECT *conn); int tls12_do_accept(TLS_CONNECT *conn); +int tls13_init(TLS_CONNECT *conn, TLS_CTX *ctx); + int tls13_do_connect(TLS_CONNECT *conn); int tls13_do_accept(TLS_CONNECT *conn); @@ -1598,27 +1641,86 @@ int tls13_process_new_session_ticket(TLS_CONNECT *conn); +int tls_cert_match_signature_algorithms(const uint8_t *cert, size_t certlen, + const int *signature_algorithms, size_t signature_algorithms_cnt, + int *first_matched_sig_alg); + +int tls_cert_chain_match_signature_algorithms_cert( + const uint8_t *cert_chain, size_t cert_chain_len, + const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt); + + + +// if cert has on subject_alt_name to match tls server_name extension +// return error (0) or success (1) to ignore the server_name +#define TLS_CERT_VERIFY_NO_SUBJECT_ALT_NAME 1 + +int tls_cert_match_server_name(const uint8_t *cert, size_t certlen, const uint8_t *host_name, size_t host_name_len); + +int tls_cert_chain_match_extensions( + const uint8_t *cert_chain, size_t cert_chain_len, + const int *signature_algorithms, size_t signature_algorithms_cnt, + const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt, // optional + const uint8_t *ca_names, size_t ca_names_len, // optional + const uint8_t *oid_filters, size_t oid_filters_len, // optional + const uint8_t *host_name, size_t host_name_len, // optional + int *prefered_sig_alg); + + +int tls13_cert_chains_select(const uint8_t *cert_chains, size_t cert_chains_len, + const int *signature_algorithms, size_t signature_algorithms_cnt, + const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt, // optional + const uint8_t *ca_names, size_t ca_names_len, // certificate_authorities optional + const uint8_t *oid_filters, size_t oid_filters_len, // optional, only in CertificateRequest + const uint8_t *host_name, size_t host_name_len, // optional, only in ClientHello + const uint8_t **certs, size_t *certs_len, size_t *certs_idx, // optional + int *prefered_sig_alg); + // Extensions -// 0. server_name (sni) +// 0. server_name (SNI): in ClientHello, EncryptedExtensions +int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host_name_len); // client only int tls_server_name_ext_to_bytes(const uint8_t *host_name, size_t host_name_len, uint8_t **out, size_t *outlen); int tls_server_name_from_bytes(const uint8_t **host_name, size_t *host_name_len, const uint8_t *ext_data, size_t ext_datalen); int tls_server_name_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen); -int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host_name_len); -// 5. status_request (ocsp stapling) + + + + + + + + +// 5. status_request (OCSP stapling) enum { TLS_certificate_status_type_ocsp = 1, }; +// set ClientHello.status_request +// server CertifcateRequest.status_request only if ClientHello.status_request send +int tls13_set_client_status_request(TLS_CONNECT *conn, + const uint8_t *status_request_responder_id_list, size_t status_request_responder_id_list_len, // optional + const uint8_t *status_request_exts, size_t status_request_exts_len); // optional +// ocsp_response is set by tls_ctx_add_certificate_list_and_key() + +// status_request in CertificateRequest +// depends on ClientHello.status_request, can not be set explicitly + int ocsp_response_verify(const uint8_t *ocsp_response, size_t ocsp_response_len, const uint8_t *ca_certs, size_t ca_certs_len); +int tls_ocsp_response_match_status_request( + const uint8_t *status_request_ocsp_response, size_t status_request_ocsp_response_len, + const uint8_t *responder_id_list, size_t responder_id_list_len, + const uint8_t *request_exts, size_t request_exts_len); + +// status_request in ClientHello int tls_ocsp_status_request_to_bytes( const uint8_t *responder_id_list, size_t responder_id_list_len, const uint8_t *request_exts, size_t request_exts_len, @@ -1639,10 +1741,7 @@ int tls_client_status_request_from_bytes(int *status_type, const uint8_t *ext_data, size_t ext_datalen); int tls_client_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen); -int tls13_set_client_status_request(TLS_CONNECT *conn, - const uint8_t *status_request_responder_id_list, size_t status_request_responder_id_list_len, // optional - const uint8_t *status_request_exts, size_t status_request_exts_len); // optional - +// Certificate 这个命名有问题,客户端证书也可以包含status_request,应该以client_hello, certificate结尾来标注函数名 int tls_server_status_request_ext_to_bytes(const uint8_t *ocsp_response, size_t ocsp_response_len, uint8_t **out, size_t *outlen); int tls_server_status_request_from_bytes(const uint8_t **ocsp_response, size_t *ocsp_response_len, @@ -1650,10 +1749,10 @@ int tls_server_status_request_from_bytes(const uint8_t **ocsp_response, size_t * int tls_server_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen); -int tls_ocsp_response_match_status_request( - const uint8_t *status_request_ocsp_response, size_t status_request_ocsp_response_len, - const uint8_t *responder_id_list, size_t responder_id_list_len, - const uint8_t *request_exts, size_t request_exts_len); + + + + // 10. supported_groups int tls_supported_groups_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen); @@ -1675,6 +1774,9 @@ int tls_process_client_ec_point_formats(const uint8_t *ext_data, size_t ext_data int tls_process_server_ec_point_formats(const uint8_t *ext_data, size_t ext_datalen); // 13. signature_algorithms + +int tls_enable_signature_algorithms_cert(TLS_CONNECT *conn); + 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); @@ -1685,7 +1787,18 @@ 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); + // 18. signed_certificate_timestamp (certificate transparency, CT) +// signed_certificate_timestamp response is set by tls_ctx_add_certificate_list_and_key() +int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx); // 这里enable的是什么?是否请求吗? +int tls_enable_signed_certificate_timestamp(TLS_CONNECT *conn); + + + +// 客户端需要一组SCT服务器的公钥列表才能够去验证SCT,我们假定这个公钥列表在CTX中 + +int tls13_signed_certificate_timestamp_verify(const uint8_t *sct_list, size_t sct_list_len); + int tls_signed_certificate_timestamp_entry_to_bytes(const uint8_t key_id[32], uint64_t timestamp, const uint8_t *signature, size_t signature_len, uint8_t **out, size_t *outlen); @@ -1698,8 +1811,12 @@ int tls_signed_certificate_timestamp_from_bytes(const uint8_t **sct_list, size_t const uint8_t **in, size_t *inlen); int tls_signed_certificate_timestamp_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); -int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx); -int tls_enable_signed_certificate_timestamp(TLS_CONNECT *conn); + + + + + + // 41. pre_shared_key int tls13_psk_identity_to_bytes(const uint8_t *ticket, size_t ticketlen, uint32_t obfuscated_ticket_age, @@ -1797,6 +1914,26 @@ int tls13_psk_key_exchange_modes_print(FILE *fp, int fmt, int ind, const uint8_t int tls13_ctx_set_psk_key_exchange_modes(TLS_CTX *ctx, int psk_ke, int psk_dhe_ke); +// 47. certificate_authorities +int tls13_enable_certificate_authorities(TLS_CONNECT *conn); +int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len, + uint8_t **out, size_t *outlen); +int tls13_certificate_authorities_from_bytes(const uint8_t **ca_names, size_t *ca_names_len, + const uint8_t *ext_data, size_t ext_datalen); +int tls13_certificate_authorities_print(FILE *fp, int fmt, int ind, + const uint8_t *ext_data, size_t ext_datalen); + +// 48. oid_filters + + + + +// 49. post_handshake_auth + +int tls13_enable_post_handshake_auth(TLS_CONNECT *conn); + + + // 50. signature_algorithms_cert int tls13_signature_algorithms_cert_ext_to_bytes(const int *algs, size_t algs_cnt, uint8_t **out, size_t *outlen); diff --git a/src/tls.c b/src/tls.c index c96ddbae..8dce7912 100644 --- a/src/tls.c +++ b/src/tls.c @@ -1999,6 +1999,8 @@ int tls_authorities_from_certs(uint8_t *names, size_t *nameslen, size_t maxlen, return 1; } +// 这个函数在语义上有问题: +// 首先我们判断的是证书链,因此函数名上应该是一个cert_chain int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_names_len, const uint8_t *certs, size_t certslen) { const uint8_t *cert; @@ -2240,6 +2242,10 @@ int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client) ctx->verify_depth = 5; + // 默认就发送一个,因为只要发送key_share,那么至少有一个group + ctx->key_exchanges_cnt = 1; + + return 1; } @@ -2343,6 +2349,11 @@ int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth error_print(); return -1; } + if (tls_authorities_from_certs(ctx->ca_names, &ctx->ca_names_len, sizeof(ctx->ca_names), + ctx->cacerts, ctx->cacertslen) != 1) { + error_print(); + return -1; + } ctx->verify_depth = depth; return 1; @@ -2651,8 +2662,6 @@ int tls_ctx_set_supported_groups(TLS_CTX *ctx, const int *groups, size_t groups_ } ctx->supported_groups_cnt = groups_cnt; - ctx->key_exchanges_cnt = (groups_cnt >= 2) ? 2 : 1; - return 1; } @@ -2716,7 +2725,7 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx) - conn->is_client = ctx->is_client; + //conn->is_client = ctx->is_client; conn->protocol = ctx->protocol; @@ -2753,10 +2762,6 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx) conn->sign_key = ctx->signkey; conn->kenc_key = ctx->kenckey; - conn->quiet = ctx->quiet; - - - conn->ctx = ctx; conn->key_exchanges_cnt = ctx->key_exchanges_cnt; diff --git a/src/tls12.c b/src/tls12.c index ba91d263..ad9deb59 100644 --- a/src/tls12.c +++ b/src/tls12.c @@ -172,6 +172,10 @@ int tls_recv_record(TLS_CONNECT *conn) } conn->recordlen = conn->record_offset; + + + // 应该判断是否为Alert这种异常状况 + return 1; } @@ -2407,7 +2411,7 @@ int tls_recv_server_finished(TLS_CONNECT *conn) return -1; } - if (!conn->quiet) + if (!conn->ctx->quiet) fprintf(stderr, "Connection established!\n"); return 1; diff --git a/src/tls13.c b/src/tls13.c index 2fe54e4a..4a46937c 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -393,13 +393,28 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s if (key_update) { int ret; - if ((ret = tls13_send_key_update(conn, 1)) <= 0) { - if (ret == TLS_ERROR_SEND_AGAIN) { - return ret; + + if (conn->is_client) { + if ((ret = tls13_send_client_key_update(conn, 1)) <= 0) { + if (ret == TLS_ERROR_SEND_AGAIN) { + return ret; + } + } else { + error_print(); + return -1; } + } else { - error_print(); - return -1; + if ((ret = tls13_send_server_key_update(conn, 1)) <= 0) { + if (ret == TLS_ERROR_SEND_AGAIN) { + return ret; + } + } else { + error_print(); + return -1; + } + + } } @@ -530,7 +545,7 @@ int tls13_do_recv(TLS_CONNECT *conn) if (seq_num > 1 && update_requested) { - if ((ret = tls13_send_key_update(conn, 0)) <= 0) { + if ((ret = tls13_send_client_key_update(conn, 0)) <= 0) { if (ret == TLS_ERROR_SEND_AGAIN) { return ret; } @@ -548,7 +563,7 @@ int tls13_do_recv(TLS_CONNECT *conn) seq_num = GETU64(conn->server_seq_num); if (seq_num > 1 && update_requested) { - if ((ret = tls13_send_key_update(conn, 0)) <= 0) { + if ((ret = tls13_send_server_key_update(conn, 0)) <= 0) { if (ret == TLS_ERROR_SEND_AGAIN) { return ret; } else { @@ -1563,6 +1578,35 @@ int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t c return 1; } +int tls13_certificate_authorities_from_bytes(const uint8_t **ca_names, size_t *ca_names_len, + const uint8_t *ext_data, size_t ext_datalen) +{ + if (tls_uint16array_from_bytes(ca_names, ca_names_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + if (*ca_names == NULL) { + error_print(); + return -1; + } + return 1; +} + +int tls13_enable_certificate_authorities(TLS_CONNECT *conn) +{ + if (!conn) { + error_print(); + return -1; + } + if (!conn->ctx->cacertslen) { + error_print(); + return -1; + } + conn->certificate_authorities = 1; + return 1; +} + int tls13_certificate_authorities_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen) { @@ -1589,6 +1633,57 @@ int tls13_certificate_authorities_print(FILE *fp, int fmt, int ind, } +/* +48. oid_filters + +struct { + OIDFilter filters<0..2^16-1>; +} OIDFilterExtension; + +struct { + opaque certificate_extension_oid<1..2^8-1>; + opaque certificate_extension_values<0..2^16-1>; +} OIDFilter; +*/ + +int tls13_oid_filters_ext_to_bytes(const uint8_t *filters, size_t filters_len, uint8_t **out, size_t *outlen) +{ + uint16_t ext_type = TLS_extension_oid_filters; + size_t ext_datalen; + + if (!outlen) { + error_print(); + return -1; + } + + ext_datalen = tls_uint16_size() + filters_len; + tls_uint16_to_bytes(ext_type, out, outlen); + tls_uint16_to_bytes(ext_datalen, out, outlen); + tls_uint16array_to_bytes(filters, filters_len, out, outlen); + + return 1; +} + +int tls13_oid_filters_from_bytes(const uint8_t **filters, size_t *filters_len, + const uint8_t *ext_data, size_t ext_datalen) +{ + if (tls_uint16array_from_bytes(filters, filters_len, &ext_data, &ext_datalen) != 1 + || tls_length_is_zero(ext_datalen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int tls13_oid_filters_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) +{ + return 1; +} + + + + + @@ -1684,35 +1779,57 @@ int tls13_client_hello_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_ case TLS_extension_supported_versions: tls13_client_supported_versions_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_signature_algorithms_cert: + tls_signature_algorithms_print(fp, fmt, ind + 4, ext_data, ext_datalen); + break; + case TLS_extension_server_name: + tls_server_name_print(fp, fmt, ind + 4, ext_data, ext_datalen); + break; + case TLS_extension_status_request: + // tls_client_status_request_print(fp, fmt, ind + 4, ext_data, ext_datalen); + break; + case TLS_extension_signed_certificate_timestamp: + format_print(fp, fmt, ind + 4, "signed_certificate_timestamp\n"); + format_bytes(fp, fmt, ind + 4, "data", ext_data, ext_datalen); // should be empty + 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_cookie: - tls13_cookie_print(fp, fmt, ind + 4, ext_data, ext_datalen); - break; - case TLS_extension_early_data: - tls13_early_data_print(fp, fmt, ind + 4, ext_data, ext_datalen); + case TLS_extension_psk_key_exchange_modes: + tls13_psk_key_exchange_modes_print(fp, fmt, ind + 4, ext_data, ext_datalen); break; case TLS_extension_pre_shared_key: tls13_client_pre_shared_key_print(fp, fmt, ind + 4, ext_data, ext_datalen); break; - case TLS_extension_psk_key_exchange_modes: - tls13_psk_key_exchange_modes_print(fp, fmt, ind + 4, ext_data, ext_datalen); + case TLS_extension_early_data: + tls13_early_data_print(fp, fmt, ind + 4, ext_data, ext_datalen); break; - - case TLS_extension_server_name: + case TLS_extension_cookie: + tls13_cookie_print(fp, fmt, ind + 4, ext_data, ext_datalen); + break; + case TLS_extension_post_handshake_auth: + format_bytes(fp, fmt, ind + 4, "data", ext_data, ext_datalen); // should be empty + break; + 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_server_certificate_type: + case TLS_extension_client_certificate_type: case TLS_extension_padding: case TLS_extension_record_size_limit: + format_bytes(fp, fmt, ind + 4, "data", ext_data, ext_datalen); + break; default: - error_print(); - return -1; + format_bytes(fp, fmt, ind + 4, "data", ext_data, ext_datalen); + //error_print(); + //return -1; } } if (dlen) { @@ -1810,13 +1927,7 @@ int tls13_server_hello_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_ return 1; } -/* -struct { - ProtocolVersion server_version; // 服务器选择的版本 - CipherSuite cipher_suite; // 服务器选择的密码套件 - Extension extensions<2..2^16-1>; // 扩展列表 -} HelloRetryRequest; -*/ + int tls13_record_set_handshake_hello_retry_request(uint8_t *record, size_t *recordlen, int legacy_version, const uint8_t random[32], @@ -2196,7 +2307,7 @@ int tls13_certificate_request_print(FILE *fp, int fmt, int ind, const uint8_t *d //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); + tls_signature_algorithms_print(fp, fmt, ind, ext_data, ext_datalen); break; case TLS_extension_client_certificate_type: //tls13_client_certificate_type_print(fp, fmt, ind, ext_data, ext_datalen); @@ -2682,6 +2793,15 @@ int tls13_certificate_entry_from_bytes(const uint8_t **cert, size_t *certlen, return 1; } +/* +struct { + opaque certificate_request_context<0..2^8-1>; + CertificateEntry certificate_list<0..2^24-1>; +} Certificate; + +if has no proper certificate chain +the client should send the Certificate with empty certificate_list content +*/ 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, @@ -2711,31 +2831,33 @@ int tls13_record_set_handshake_certificate(uint8_t *record, size_t *recordlen, cert_list = data; tls_uint24_to_bytes(0, &data, &len); - // first (entity) cert entry - if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { - error_print(); - return -1; - } - if (tls13_certificate_entry_to_bytes(cert, certlen, - entity_status_request_ocsp_response, entity_status_request_ocsp_response_len, - entity_signed_certificate_timestamp, entity_signed_certificate_timestamp_len, - &data, &cert_list_len) != 1) { - error_print(); - return -1; - } - // ca certs entries - while (certslen) { + // client might send null certificate_list + if (certs && certslen) { + // first (entity) cert entry if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { error_print(); return -1; } - if (tls13_certificate_entry_to_bytes(cert, certlen, NULL, 0, NULL, 0, &data, &cert_list_len) != 1) { + if (tls13_certificate_entry_to_bytes(cert, certlen, + entity_status_request_ocsp_response, entity_status_request_ocsp_response_len, + entity_signed_certificate_timestamp, entity_signed_certificate_timestamp_len, + &data, &cert_list_len) != 1) { error_print(); return -1; } + // ca certs entries + while (certslen) { + if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) { + error_print(); + return -1; + } + if (tls13_certificate_entry_to_bytes(cert, certlen, NULL, 0, NULL, 0, &data, &cert_list_len) != 1) { + error_print(); + return -1; + } + } } tls_uint24array_to_bytes(NULL, cert_list_len, &cert_list, &datalen); - if (tls_record_set_handshake(record, recordlen, type, NULL, datalen) != 1) { error_print(); return -1; @@ -2770,6 +2892,9 @@ int _tls13_record_get_handshake_certificate(const uint8_t *record, } */ + +// even if status_request, signed_certificate_timestamp not requested +// server/client can still return certificate with these two extensions int tls13_record_get_handshake_certificate(const uint8_t *record, const uint8_t **request_context, size_t *request_context_len, uint8_t *cert_chain, size_t *cert_chain_len, size_t cert_chain_maxlen, @@ -2815,7 +2940,6 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, *cert_chain_len = 0; x509_cert_to_der(cert, certlen, &cert_chain, cert_chain_len); - fprintf(stderr, ">>>>>>>>> cert_chain_len = %zu\n", *cert_chain_len); while (cert_list_len) { const uint8_t *status_request_ocsp_response; @@ -2830,17 +2954,12 @@ int tls13_record_get_handshake_certificate(const uint8_t *record, error_print(); return -1; } + // 这里的解析可能是有问题的 - // 这里的解析可能是有问题的 x509_cert_to_der(cert, certlen, &cert_chain, cert_chain_len); - fprintf(stderr, ">>>>>>>>> cert_chain_len = %zu\n", *cert_chain_len); } - - fprintf(stderr, ">>>>>>>>> cert_chain_len = %zu\n", *cert_chain_len); - - return 1; } @@ -3089,8 +3208,20 @@ int tls13_record_get_message_hash(uint8_t *record, size_t *recordlen) +int tls_handshake_digest_print(FILE *fp, int fmt, int ind, const char *label, const DIGEST_CTX *dgst_ctx) +{ + DIGEST_CTX tmp_ctx; + uint8_t dgst[64]; + size_t dgstlen; + tmp_ctx = *dgst_ctx; + digest_finish(&tmp_ctx, dgst, &dgstlen); + + format_bytes(fp, fmt, ind, label, dgst, dgstlen); + + return 1; +} @@ -3137,44 +3268,13 @@ Auth | {CertificateVerify*} [Application Data] <-------> [Application Data] + + + */ -/* -如果执行0-RTT(前提是CTX,CONN中准备了session) - -那么ClientHello中必须包含 - pre_shared_key (从session中获得1个活着多个) - early_data (empty) - key_share 虽然是可选的,但是我们强制实现 - -客户端发送完ClientHello之后,就可以先发送一个ApplicationData,因此这个流程和默认的是不一样的 - -然后接收: - ServerHello - 必须包含key_share - EncryptedExtensions - (必须包含early_data,否则和常规的是一样的) - 也就是说获得了EE才知道后续的状态 - Finished 采用0-RTT时状态变了 - - -客户端如何决定是否用PSK模式? - - 我们可以在TLS_CTX中设定psk模式,并且psk就存储在CTX中 - -客户端通过ClientHello.pre_shared_key 来请求启用PSK模式 -服务器通过ServerHello.pre_shared_key 来响应,或者不包含pre_shared_key来拒绝,以回到完整握手 -PSK模式的握手过程和Full握手是不同的 - - -客户端通过ClientHello.early_data(empty)来请求启动0-RTT -服务器在EncryptedExtensions.early_data来响应 -如果响应了early_data,那么握手过程在PSK模式上又增加了消息 -*/ - - int tls_key_exchange_modes_print(FILE *fp, int fmt, int ind, const char *label, int modes) { format_print(fp, fmt, ind, "%s:", label); @@ -3192,100 +3292,9 @@ int tls_key_exchange_modes_print(FILE *fp, int fmt, int ind, const char *label, return 1; } -// CTX经过多次设置之后,其中参数可能存在不一致的情况 -// 我们不在CTX中进行检查了,我们在tls_init中进行检查和设置,保持一致性 - -int tls13_ctx_prepare(TLS_CTX *ctx) -{ - size_t i; - - // cipher_suites - format_print(stderr, 0, 0, "ctx->cipher_suites\n"); - for (i = 0; i < ctx->cipher_suites_cnt; i++) { - format_print(stderr, 0, 4, "%s\n", tls_cipher_suite_name(ctx->cipher_suites[i])); - } - // supported_groups - format_print(stderr, 0, 0, "ctx->supported_groups\n"); - for (i = 0; i < ctx->supported_groups_cnt; i++) { - format_print(stderr, 0, 4, "%s\n", tls_named_curve_name(ctx->supported_groups[i])); - } - // signature_algorithms - format_print(stderr, 0, 0, "ctx->signature_algorithms\n"); - for (i = 0; i < ctx->signature_algorithms_cnt; i++) { - format_print(stderr, 0, 4, "%s\n", tls_signature_scheme_name(ctx->signature_algorithms[i])); - } - // psk_key_exchange_modes - tls_key_exchange_modes_print(stderr, 0, 0, "psk_key_exchange_modes", ctx->psk_key_exchange_modes); - - // group sm2p256v1 depends on TLS_SM4_GCM_SM3 or TLS_SM4_CCM_SM3 - if (ctx->supported_groups_cnt) { - if (tls_type_is_in_list(TLS_curve_sm2p256v1, ctx->supported_groups, ctx->supported_groups_cnt)) { - if (!tls_type_is_in_list(TLS_cipher_sm4_gcm_sm3, ctx->cipher_suites, ctx->cipher_suites_cnt)) { - error_print(); - return -1; - } - } - } - - /* - if (ctx->supported_groups_cnt && ctx->signature_algorithms_cnt) { - ctx->key_exchange_modes |= TLS_KE_CERT_DHE; - } - tls_key_exchange_modes_print(stderr, 0, 0, "key_exchange_modes", ctx->key_exchange_modes); - */ - - /* - if (!ctx->key_exchange_modes) { - error_print(); - return -1; - } - */ - - /* - if (ctx->key_exchange_modes & (TLS_KE_CERT_DHE|TLS_KE_PSK_DHE)) { - ctx->key_exchanges_cnt = 1; - } - */ - - return 1; -} - -int tls13_handshake_prepare(TLS_CONNECT *conn) -{ - if (tls13_ctx_prepare(conn->ctx) != 1) { - error_print(); - return -1; - } - - return 1; -} - /* -这里面分为几个不同阶段的密钥 - - - * early_data - client_early_traffic_secret - 因为early_data是一个单向的过程,因为只有客户端的密钥,没有服务器端的 - 这个密钥完全是在客户端确定的 - 客户端用的第一个PSK,就是early_data的密钥 - - - * handshake的密钥 - client_handshake_traffic_secret - server_handshake_traffic_secret - 这个过程只用于握手阶段 - 客户端必须在接收到ServerHello的时候,才能计算出 - 因为在ServerHello中才有 服务器的DH, PSK等信息 - - 服务器呢? - 服务器是在发送ServerHello的阶段生成密钥 - - 因此客户端和服务器端都是在ServerHello阶段生成handshake密钥 - - 0 | v @@ -3417,8 +3426,99 @@ int tls13_generate_handshake_keys(TLS_CONNECT *conn) return 1; } +int tls13_init(TLS_CONNECT *conn, TLS_CTX *ctx) +{ + size_t i; + if (!ctx->supported_versions_cnt) { + error_print(); + return -1; + } + + if (!ctx->cipher_suites_cnt) { + error_print(); + return -1; + } + + + memset(conn, 0, sizeof(*conn)); + + conn->ctx = ctx; + + conn->is_client = ctx->is_client; + + conn->protocol = ctx->protocol; + + + + conn->new_session_ticket = ctx->new_session_ticket; + + + /* + extensions depends on key_exchange_modes + + + switch (key_exchange_mode) + case CERT_DHE: + * supported_groups ctx->supported_groups_cnt != 0 + * signature_algorithms ctx->signature_algorithms_cnt != 0 + * key_share generated in ClientHello, so always ok + * [signature_algorithms_cert] + * [certificate_authorities] + + case PSK_DHE: + * supported_groups + * psk_key_exchange_modes ctx->psk_key_exchange_modes has psk_dhe_ke + * pre_shared_key call tls13_add_pre_shared_key, tls13_add_pre_shared_key_from_session_file after tls13_init + * key_share + * [early_data] + * [signature_algorithms] + * [signature_algorithms_cert] + + case PSK: + * psk_key_exchange_modes ctx->psk_key_exchange_modes has psk_ke + * pre_shared_key + * [early_data] + * [supported_groups] + * [signature_algorithms] + * [signature_algorithms_cert] + */ + + + fprintf(stderr, "tls13_init\n"); + + // key_exchange_modes + conn->key_exchange_modes = ctx->psk_key_exchange_modes; + if (ctx->supported_groups_cnt && ctx->signature_algorithms_cnt) { + conn->key_exchange_modes = TLS_KE_CERT_DHE; + } + if (!ctx->supported_groups_cnt) { + conn->key_exchange_modes &= ~(TLS_KE_CERT_DHE|TLS_KE_PSK_DHE); + } + if (!conn->key_exchange_modes) { + error_print(); + return -1; + } + + // TLS_KE_PSK_DHE|TLS_KE_PSK depends on pre_shared_key + // but pre_shared_key is set by tls13_add_pre_shared_key, tls13_add_pre_shared_key_from_session_file + // after tls13_init + + // key_share + if (conn->key_exchange_modes & (TLS_KE_CERT_DHE|TLS_KE_PSK_DHE)) { + conn->key_share = 1; + } + + conn->signed_certificate_timestamp = ctx->signed_certificate_timestamp; + + // early_data + conn->early_data = ctx->early_data; + conn->max_early_data_size = ctx->max_early_data_size; + + return 1; +} + int tls13_send_client_hello(TLS_CONNECT *conn) @@ -3446,6 +3546,31 @@ int tls13_send_client_hello(TLS_CONNECT *conn) // legacy_session_id conn->session_id_len = 0; + + // exts in CH (RFC 8446 page 37), only oid_filter not in CH + // * supported_versions + // * signature_algorithms + // * signature_algorithms_cert + // * certificate_authorities + // * server_name + // * status_request + // * signed_certificate_timestamp + // * supported_groups + // * key_share + // * psk_key_exchange_modes + // * pre_shared_key + // * early_data (only in ClientHello1) + // * cookie (only in ClientHello2) + // * post_handshake_auth: client support post handshake auth + // * max_fragment_length + // * use_srtp + // * heartbeat + // * application_layer_protocol_negotiation + // * server_certificate_type: if client accept raw/x509 + // * client_certificate_type: if client sned raw/x509 + // * padding + + // supported_versions if (tls13_client_supported_versions_ext_to_bytes(conn->ctx->supported_versions, conn->ctx->supported_versions_cnt, &pexts, &extslen) != 1) { @@ -3453,34 +3578,6 @@ int tls13_send_client_hello(TLS_CONNECT *conn) return -1; } - /* - extensions depends on key_exchange_modes - - switch (key_exchange_mode) - case CERT_DHE: - * supported_groups - * signature_algorithms - * [key_share] - * [signature_algorithms_cert] - - case PSK_DHE: - * supported_groups - * psk_key_exchange_modes - * pre_shared_key - * [key_share] - * [early_data] - * [signature_algorithms] - * [signature_algorithms_cert] - - case PSK: - * psk_key_exchange_modes - * pre_shared_key - * [early_data] - * [supported_groups] - * [signature_algorithms] - * [signature_algorithms_cert] - */ - // supported_groups if (conn->ctx->supported_groups_cnt) { if (tls_supported_groups_ext_to_bytes(conn->ctx->supported_groups, @@ -3499,10 +3596,29 @@ int tls13_send_client_hello(TLS_CONNECT *conn) } } + // signature_algorithms_cert + if (conn->signature_algorithms_cert) { + if (tls13_signature_algorithms_cert_ext_to_bytes(conn->ctx->signature_algorithms, + conn->ctx->signature_algorithms_cnt, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + + // certificate_authorities + if (conn->certificate_authorities) { + if (tls13_certificate_authorities_ext_to_bytes( + conn->ctx->ca_names, conn->ctx->ca_names_len, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + // key_share if (conn->key_share) { size_t i; + // empty ClientHello.key_share is allowed for (i = 0; i < conn->ctx->key_exchanges_cnt && i < conn->ctx->supported_groups_cnt; i++) { int curve_oid = tls_named_curve_oid(conn->ctx->supported_groups[i]); if (x509_key_generate(&conn->key_exchanges[i], @@ -3520,23 +3636,25 @@ int tls13_send_client_hello(TLS_CONNECT *conn) } } - // psk_key_exchange_modes - if (conn->key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) { - if (tls13_psk_key_exchange_modes_ext_to_bytes(conn->key_exchange_modes, &pexts, &extslen) != 1) { - error_print(); - return -1; - } - } - // server_name if (conn->server_name) { - if (tls_server_name_ext_to_bytes(conn->host_name, conn->host_name_len, &pexts, &extslen) != 1) { + if (tls_server_name_ext_to_bytes( + conn->host_name, conn->host_name_len, &pexts, &extslen) != 1) { error_print(); return -1; } } - // status_request + // psk_key_exchange_modes + if (conn->key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) { + if (tls13_psk_key_exchange_modes_ext_to_bytes( + conn->key_exchange_modes, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + + // status_request (hint only) if (conn->status_request) { if (tls_client_status_request_ext_to_bytes(TLS_certificate_status_type_ocsp, conn->status_request_responder_id_list, conn->status_request_responder_id_list_len, @@ -3545,19 +3663,32 @@ int tls13_send_client_hello(TLS_CONNECT *conn) error_print(); return -1; } + conn->status_request = 0; // to track CertificateRequest.status_request } - // signed_certificate_timestamp - if (conn->ctx->signed_certificate_timestamp) { - if (tls_ext_to_bytes(TLS_extension_signed_certificate_timestamp, NULL, 0, &pexts, &extslen) != 1) { + // signed_certificate_timestamp (hint only) + if (conn->signed_certificate_timestamp) { + if (tls_ext_to_bytes(TLS_extension_signed_certificate_timestamp, NULL, 0, + &pexts, &extslen) != 1) { + error_print(); + return -1; + } + conn->signed_certificate_timestamp = 0; // to track CertificateRequest.signed_certificate_timestamp + } + + // early_data + if (conn->early_data) { + if (tls_ext_to_bytes(TLS_extension_early_data, NULL, 0, + &pexts, &extslen) != 1) { error_print(); return -1; } } - // early_data - if (conn->early_data) { - if (tls_ext_to_bytes(TLS_extension_early_data, NULL, 0, &pexts, &extslen) != 1) { + // post_handshake_auth + if (conn->post_handshake_auth) { + if (tls_ext_to_bytes(TLS_extension_post_handshake_auth, NULL, 0, + &pexts, &extslen) != 1) { error_print(); return -1; } @@ -3658,6 +3789,26 @@ int tls13_send_client_hello(TLS_CONNECT *conn) return 1; } +/* +recv HelloRetryRequest: + * set conn->protocol + * set conn->cipher_suite, conn->cipher, conn->digest + * set conn->key_exchange_group + * set conn->dgst_ctx <= ClientHello, HelloRetryRequest, ClientHello2 + +recv ServerHello after HelloRetryRequest: + * check ServerHello.protocol == conn->protocol + * check ServerHello.cipher_suite == conn->cipher_suite + * check ServerHello.key_share.group == conn->key_exchange_group + * conn->dgst_ctx <= ServerHello + +recv ServerHello without HelloRetryRequest: + * set conn->protocol + * set conn->cipher_suite, conn->cipher, conn->digest + * set conn->key_exchange_group + * set conn->dgst_ctx <= ClientHello +*/ + int tls13_recv_hello_retry_request(TLS_CONNECT *conn) { int ret; @@ -3667,7 +3818,7 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) const uint8_t *handshake_data; size_t handshake_datalen; - // server_hello + // HelloRetryRequest int legacy_version; const uint8_t *random; const uint8_t *legacy_session_id_echo; @@ -3688,7 +3839,6 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) int selected_version; int key_exchange_group; - tls_trace("recv HelloRetryRequest*\n"); if ((ret = tls_recv_record(conn)) != 1) { @@ -3697,49 +3847,43 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) } return ret; } + if (tls_record_protocol(conn->record) != TLS_protocol_tls12) { error_print(); tls13_send_alert(conn, TLS_alert_protocol_version); return -1; } - // is ServerHello ? - if (tls_record_get_handshake(conn->record, - &handshake_type, &handshake_data, &handshake_datalen) != 1) { - error_print(); - tls13_send_alert(conn, TLS_alert_decode_error); - return -1; - } - if (handshake_type == TLS_handshake_server_hello) { - tls_trace(" no HelloRetryRequest\n"); - return 0; - } - - // HelloRetryRequest - tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); - - if ((ret = tls13_record_get_handshake_hello_retry_request(conn->record, - &legacy_version, &random, - &legacy_session_id_echo, &legacy_session_id_echo_len, - &cipher_suite, &legacy_compress_meth, &exts, &extslen)) < 0) { + // the record might be Alert? + if ((ret = tls_record_get_handshake(conn->record, + &handshake_type, &handshake_data, &handshake_datalen)) < 0) { error_print(); tls13_send_alert(conn, TLS_alert_decode_error); return -1; } else if (ret == 0) { error_print(); - tls13_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (handshake_type != TLS_handshake_hello_retry_request) { + tls_trace(" no HelloRetryRequest\n"); + return 0; + } + + tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); + + if ((ret = tls13_record_get_handshake_hello_retry_request(conn->record, + &legacy_version, &random, + &legacy_session_id_echo, &legacy_session_id_echo_len, + &cipher_suite, &legacy_compress_meth, &exts, &extslen)) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); return -1; } conn->hello_retry_request = 1; - // update key_exchange_modes - conn->key_exchange_modes &= ~TLS_KE_PSK; - if (!conn->key_exchange_modes) { - error_print(); - tls13_send_alert(conn, TLS_alert_handshake_failure); - return -1; - } + // HelloRetryRequest disable early_data + conn->early_data = 0; // legacy_version @@ -3766,12 +3910,12 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) tls13_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(); tls13_send_alert(conn, TLS_alert_internal_error); return -1; } + conn->cipher_suite = cipher_suite; // legacy_compression_method if (legacy_compress_meth != 0) { @@ -3791,6 +3935,11 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) return -1; } + // exts in HRR + // * supported_versions + // * key_share + // * cookie + switch (ext_type) { case TLS_extension_supported_versions: case TLS_extension_key_share: @@ -3814,6 +3963,11 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) break; case TLS_extension_key_share: + if (!conn->key_share) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } if (key_share) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); @@ -3831,6 +3985,7 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) } cookie = ext_data; cookie_len = ext_datalen; + conn->cookie = 1; break; default: @@ -3865,7 +4020,6 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) } conn->protocol = selected_version; - // key_share if (!key_share) { error_print(); @@ -3884,6 +4038,14 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } + // HelloRetryRequest must choose a group not in ClientHello.key_share + while (conn->key_exchanges_cnt--) { + if (key_exchange_group == tls_named_curve_from_oid( + conn->key_exchanges[conn->key_exchanges_cnt].algor_param)) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + } + } conn->key_exchange_group = key_exchange_group; // cookie @@ -3899,7 +4061,6 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) } memcpy(conn->cookie_buf, cookie_data, cookie_datalen); conn->cookie_len = cookie_datalen; - conn->cookie = 1; } // ClientHello1 @@ -3910,6 +4071,8 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) message_hash[2] = 0; message_hash[3] = 32; + // 我猜如果用了HRR,那么客户端实际上并没有保存ClientHello的数据,而是用ClientHello的哈希值来计算后续的 + if (digest_init(&conn->dgst_ctx, conn->digest) != 1 || digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1 || digest_finish(&conn->dgst_ctx, message_hash + 4, &dgstlen) != 1) { @@ -3932,6 +4095,64 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn) return 1; } +int tls13_client_hello_again_psk_update(TLS_CONNECT *conn) +{ + const uint8_t *psk_identities; + const uint8_t *psk_keys; + uint8_t tmp_identities_buf[sizeof(conn->psk_identities)]; + uint8_t *tmp_identities = tmp_identities_buf; + size_t tmp_identities_len = 0; + uint8_t tmp_keys_buf[sizeof(conn->psk_keys)]; + uint8_t *tmp_keys = tmp_keys_buf; + size_t tmp_keys_len = 0; + size_t tmp_cipher_suites_cnt = 0; + size_t i; + + if (!conn) { + error_print(); + return -1; + } + psk_identities = conn->psk_identities; + psk_keys = conn->psk_keys; + + for (i = 0; i < conn->psk_cipher_suites_cnt; i++) { + const uint8_t *identity; + size_t identity_len; + uint32_t obfuscated_ticket_age; + const uint8_t *key; + size_t key_len; + + if (tls13_psk_identity_from_bytes(&identity, &identity_len, &obfuscated_ticket_age, &psk_identities, &conn->psk_identities_len) != 1 + || tls_uint8array_from_bytes(&key, &key_len, &psk_keys, &conn->psk_keys_len) != 1) { + gmssl_secure_clear(tmp_keys_buf, sizeof(tmp_keys_buf)); + error_print(); + return -1; + } + if (conn->psk_cipher_suites[i] == conn->cipher_suite) { + tls13_psk_identity_to_bytes(identity, identity_len, obfuscated_ticket_age, &tmp_identities, &tmp_identities_len); + tls_uint16array_to_bytes(key, key_len, &tmp_keys, &tmp_keys_len); + tmp_cipher_suites_cnt++; + } + } + if (conn->psk_identities_len || conn->psk_keys_len) { + gmssl_secure_clear(tmp_keys_buf, sizeof(tmp_keys_buf)); + error_print(); + return -1; + } + + memcpy(conn->psk_identities, tmp_identities_buf, tmp_identities_len); + conn->psk_identities_len = tmp_identities_len; + memcpy(conn->psk_keys, tmp_keys_buf, tmp_keys_len); + conn->psk_keys_len = tmp_keys_len; + for (i = 0; i < tmp_cipher_suites_cnt; i++) { + conn->psk_cipher_suites[i] = conn->cipher_suite; + } + conn->psk_cipher_suites_cnt = tmp_cipher_suites_cnt; + + gmssl_secure_clear(tmp_keys_buf, sizeof(tmp_keys_buf)); + return 1; +} + int tls13_send_client_hello_again(TLS_CONNECT *conn) { int ret; @@ -3955,6 +4176,14 @@ int tls13_send_client_hello_again(TLS_CONNECT *conn) return -1; } + // Extensions + + // keep ClientHello extensions except + // * key_share - generate a new key_exchange based on conn->key_exchange_group + // * pre_shared_key - remove PSKs not compatible with conn->cipher_suite + // * early_data - disable early_data + // * cookie - echo cookie if exist + // supported_versions if (tls13_client_supported_versions_ext_to_bytes(conn->ctx->supported_versions, conn->ctx->supported_versions_cnt, &pexts, &extslen) != 1) { @@ -3980,6 +4209,23 @@ int tls13_send_client_hello_again(TLS_CONNECT *conn) } } + // signature_algorithms_cert + if (conn->signature_algorithms_cert) { + if (tls13_signature_algorithms_cert_ext_to_bytes(conn->ctx->signature_algorithms, + conn->ctx->signature_algorithms_cnt, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + + // server_name + if (conn->server_name) { + if (tls_server_name_ext_to_bytes(conn->host_name, conn->host_name_len, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + // key_share (re-generated) if ((curve_oid = tls_named_curve_oid(conn->key_exchange_group)) == OID_undef) { error_print(); @@ -4006,14 +4252,8 @@ int tls13_send_client_hello_again(TLS_CONNECT *conn) return -1; } } - - // server_name - if (conn->server_name) { - if (tls_server_name_ext_to_bytes(conn->host_name, conn->host_name_len, &pexts, &extslen) != 1) { - error_print(); - return -1; - } - } + // update key_exchange_modes (disable PSK-only) + conn->key_exchange_modes &= ~TLS_KE_PSK; // status_request if (conn->status_request) { @@ -4034,20 +4274,20 @@ int tls13_send_client_hello_again(TLS_CONNECT *conn) } } - // early_data - if (conn->key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) { - if (conn->early_data) { - if (tls_ext_to_bytes(TLS_extension_early_data, NULL, 0, &pexts, &extslen) != 1) { - error_print(); - return -1; - } + // post_handshake_auth + if (conn->post_handshake_auth) { + if (tls_ext_to_bytes(TLS_extension_post_handshake_auth, NULL, 0, + &pexts, &extslen) != 1) { + error_print(); + return -1; } } + // early_data must not in ClientHello2 + // cookie if (conn->cookie) { - if (tls13_cookie_ext_to_bytes(conn->cookie_buf, conn->cookie_len, - &pexts, &extslen) != 1) { + if (tls13_cookie_ext_to_bytes(conn->cookie_buf, conn->cookie_len, &pexts, &extslen) != 1) { error_print(); return -1; } @@ -4055,18 +4295,26 @@ int tls13_send_client_hello_again(TLS_CONNECT *conn) // pre_shared_key if (conn->pre_shared_key) { - uint8_t *ptruncated_exts = pexts; - size_t truncated_extslen = extslen; - uint8_t binders[256]; - uint8_t *pbinders = binders; - size_t binderslen = 0; - if (!conn->psk_identities_len || !conn->psk_keys_len || !conn->psk_cipher_suites_cnt ) { error_print(); return -1; } + if (tls13_client_hello_again_psk_update(conn) != 1) { + error_print(); + return -1; + } + if (!conn->psk_cipher_suites_cnt) { + conn->pre_shared_key = 0; + } + } + if (conn->pre_shared_key) { + uint8_t *ptruncated_exts = pexts; + size_t truncated_extslen = extslen; + uint8_t binders[256]; + uint8_t *pbinders = binders; + size_t binderslen = 0; // output pre_shared_key ext with empty binders if (tls13_psk_binders_generate_empty( @@ -4142,6 +4390,26 @@ int tls13_send_client_hello_again(TLS_CONNECT *conn) return 1; } + +/* +recv HelloRetryRequest: + * set conn->protocol + * set conn->cipher_suite, conn->cipher, conn->digest + * set conn->key_exchange_group + * set conn->dgst_ctx <= ClientHello, HelloRetryRequest, ClientHello2 + +recv ServerHello after HelloRetryRequest: + * check ServerHello.protocol == conn->protocol + * check ServerHello.cipher_suite == conn->cipher_suite + * check ServerHello.key_share.group == conn->key_exchange_group + * conn->dgst_ctx <= ServerHello + +recv ServerHello without HelloRetryRequest: + * set conn->protocol + * set conn->cipher_suite, conn->cipher, conn->digest + * set conn->key_exchange_group + * set conn->dgst_ctx <= ClientHello +*/ int tls13_recv_server_hello(TLS_CONNECT *conn) { int ret; @@ -4163,6 +4431,7 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) size_t pre_shared_key_len; int selected_version; + int server_key_exchange_mode = 0; tls_trace("recv ServerHello\n"); @@ -4200,6 +4469,13 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) } // random + if (conn->hello_retry_request) { + if (memcmp(random, conn->server_random, 32) == 0) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + } memcpy(conn->server_random, random, 32); // legacy_session_id_echo @@ -4243,6 +4519,16 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) return -1; } + // exts in SH + // * supported_versions + // * key_share + // * pre_shared_key (not in HRR) + // + // + // ServerHello.key_share if only ClientHello.key_share + // ServerHello.pre_shared_key if only ClientHello.pre_shared_key + // if HelloRetryRequest, key_share must exist + switch (ext_type) { case TLS_extension_supported_versions: case TLS_extension_key_share: @@ -4267,6 +4553,7 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) break; case TLS_extension_key_share: + // ServerHello.key_share if only ClientHello.key_share if (!conn->key_share) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); @@ -4282,6 +4569,7 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) break; case TLS_extension_pre_shared_key: + // ServerHello.pre_shared_key if only ClientHello.pre_shared_key if (!conn->pre_shared_key) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); @@ -4303,12 +4591,55 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) } } - // supported_versions if (!supported_versions) { error_print(); tls13_send_alert(conn, TLS_alert_missing_extension); return -1; } + + // if HelloRetryRequest, key_share must exist + if (conn->hello_retry_request) { + if (!key_share) { + error_print(); + tls13_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + } + + // key_exchange_mode + // implicitly sent through ServerHello exts + // + // * key_share + pre_shared_key PSK_DHE + // * key_share CERT_DHE + // * pre_shared_key PSK + // * (none) error + // + if (pre_shared_key) { + if (key_share) + server_key_exchange_mode = TLS_KE_PSK_DHE; + else server_key_exchange_mode = TLS_KE_PSK; + } else { + if (key_share) { + server_key_exchange_mode = TLS_KE_CERT_DHE; + } else { + error_print(); + tls13_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + } + + + // set key_exchange_mode + conn->key_exchange_modes &= server_key_exchange_mode; + + if (!conn->key_exchange_modes) { + error_print(); + tls13_send_alert(conn, TLS_alert_handshake_failure); + return -1; + } + + + // supported_versions if (tls13_server_supported_versions_from_bytes( &selected_version, supported_versions, supported_versions_len) != 1) { tls13_send_alert(conn, TLS_alert_decode_error); @@ -4336,6 +4667,7 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) conn->protocol = selected_version; } + // key_share if (key_share) { int key_exchange_group; @@ -4353,6 +4685,7 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_decode_error); return -1; } + // compatible with/without HRR while (conn->key_exchange_idx < conn->key_exchanges_cnt) { if (conn->key_exchanges[conn->key_exchange_idx].algor_param == tls_named_curve_oid(key_exchange_group)) { @@ -4400,63 +4733,36 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) return -1; } - // 这里应该只是一个reference - // 当采用session_ticket的时候,服务器没有预设的psk_keys, - // 但是我们可以把解密的密钥存储在psk_keys中 - // 不需要保存一个独立的密钥 + // TODO: change psk from buf to reference memcpy(conn->psk, key, keylen); conn->psk_len = keylen; } - /* - key_exchange_modes - PSK_DHE - * pre_shared_key - * key_share - - PSK - * pre_shared_key - - CERT_DHE - * key_share - */ - - if (pre_shared_key && key_share) { - conn->key_exchange_modes &= TLS_KE_PSK_DHE; - } else if(pre_shared_key) { - conn->key_exchange_modes &= TLS_KE_PSK; - } else if (key_share) { - conn->key_exchange_modes &= TLS_KE_CERT_DHE; - } - - if (!conn->key_exchange_modes) { - error_print(); - return -1; - } - - if (!conn->hello_retry_request) { + if (conn->hello_retry_request) { + // dgst_ctx <= ServerHello + if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_internal_error); + return -1; + } + tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); + } else { if (digest_init(&conn->dgst_ctx, conn->digest) != 1 - || digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + // dgst_ctx <= ClientHello + || digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1 + // dgst_ctx <= ServerHello + || digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { error_print(); return -1; } + tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); } - if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { - error_print(); - tls13_send_alert(conn, TLS_alert_internal_error); - return -1; - } - - // 这里怎么没有更新服务器的seq_num if (conn->client_certs_len) { sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5); } - // 接受到ServerHello之后,双方已经可以确定握手阶段的密钥了 - // 但是服务器端的握手密钥可以初始化了,客户端的必须等到send_end_of_early_data完成的时候才能变更 - if (tls13_generate_handshake_keys(conn) != 1) { error_print(); return -1; @@ -4465,28 +4771,6 @@ int tls13_recv_server_hello(TLS_CONNECT *conn) return 1; } - - - - - - - - - - - - - - - - - - - - - - int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) { int ret; @@ -4495,16 +4779,9 @@ int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) const uint8_t *supported_groups = NULL; size_t supported_groups_len; - const uint8_t *alpn = NULL; - size_t alpn_len; - const uint8_t *max_fragment_length = NULL; - size_t max_fragment_length_len; - const uint8_t *record_size_limit = NULL; - size_t record_size_limit_len; int server_name = 0; int early_data = 0; - int padding = 0; printf("recv {EncryptedExtensions}\n"); @@ -4522,8 +4799,18 @@ int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_bad_record_mac); return -1; } + tls_seq_num_incr(conn->server_seq_num); + + + if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + error_print(); + return -1; + } tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + tls_handshake_digest_print(stderr, 0, 0, "EncryptedExtension", &conn->dgst_ctx); + + if ((ret = tls13_record_get_handshake_encrypted_extensions(conn->plain_record, &exts, &extslen)) < 0) { error_print(); @@ -4546,11 +4833,21 @@ int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) return -1; } + // Exts in EE (see RFC 8446 page 37) + // * supported_groups + // * server_name + // * early_data + // * application_layer_protocol_negotiation + // * use_srtp + // * client_certificate_type + // * server_certificate_type + // * max_fragment_length + // * heartbeat + // * record_size_limit (RFC 8449) + + switch (ext_type) { case TLS_extension_supported_groups: - case TLS_extension_application_layer_protocol_negotiation: - case TLS_extension_max_fragment_length: - case TLS_extension_record_size_limit: if (!ext_data) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); @@ -4569,6 +4866,11 @@ int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) switch (ext_type) { case TLS_extension_supported_groups: + if (!conn->ctx->supported_groups_cnt) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } if (supported_groups) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); @@ -4577,6 +4879,11 @@ int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) break; case TLS_extension_server_name: + if (!conn->server_name) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } if (server_name) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); @@ -4586,6 +4893,11 @@ int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) break; case TLS_extension_early_data: + if (!conn->early_data) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } if (early_data) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); @@ -4595,53 +4907,15 @@ int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) break; case TLS_extension_application_layer_protocol_negotiation: - if (alpn) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - alpn = ext_data; - alpn_len = ext_datalen; - break; - + case TLS_extension_use_srtp: + case TLS_extension_client_certificate_type: + case TLS_extension_server_certificate_type: case TLS_extension_max_fragment_length: - if (max_fragment_length) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - max_fragment_length = ext_data; - max_fragment_length_len = ext_datalen; - break; - + case TLS_extension_heartbeat: case TLS_extension_record_size_limit: - if (record_size_limit) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - record_size_limit = ext_data; - record_size_limit_len = ext_datalen; break; - case TLS_extension_padding: - if (padding) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - padding = 1; - break; - - // extensions must not be included - case TLS_extension_supported_versions: - case TLS_extension_key_share: - case TLS_extension_psk_key_exchange_modes: - case TLS_extension_pre_shared_key: - case TLS_extension_signature_algorithms: - case TLS_extension_certificate_authorities: - case TLS_extension_status_request: - case TLS_extension_signed_certificate_timestamp: + default: error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; @@ -4649,29 +4923,11 @@ int tls13_recv_encrypted_extensions(TLS_CONNECT *conn) } // server_name - if (server_name) { - if (!conn->server_name) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - } + // if or not server support SNI, do nothing // early_data - if (early_data) { - if (!conn->early_data) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - } + conn->early_data = early_data; // server allow EarlyData messages - if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { - error_print(); - return -1; - } - - tls_seq_num_incr(conn->server_seq_num); return 1; } @@ -4786,7 +5042,7 @@ int tls_cert_match_server_name(const uint8_t *cert, size_t certlen, const uint8_ error_print(); return -1; } else if (ret == 0) { - return 0; + return TLS_CERT_VERIFY_NO_SUBJECT_ALT_NAME; } if (subject_dns_name_len != host_name_len || memcmp(subject_dns_name, host_name, host_name_len) != 0) { @@ -4795,255 +5051,144 @@ int tls_cert_match_server_name(const uint8_t *cert, size_t certlen, const uint8_ return 1; } -int tls_cert_chain_match_certificate_authorities(const uint8_t *cert_chain, size_t cert_chain_len, - const uint8_t *certificate_authorities, size_t certificate_authorities_len) +int tls_cert_chain_match_extensions( + const uint8_t *cert_chain, size_t cert_chain_len, + const int *signature_algorithms, size_t signature_algorithms_cnt, + const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt, // optional + const uint8_t *ca_names, size_t ca_names_len, // optional + const uint8_t *oid_filters, size_t oid_filters_len, // optional + const uint8_t *host_name, size_t host_name_len, // optional + int *prefered_sig_alg) { int ret; const uint8_t *cert; size_t certlen; + int sig_alg; - if (!cert_chain || !cert_chain_len || !certificate_authorities || !certificate_authorities_len) { + if (!cert_chain || !cert_chain_len + || !signature_algorithms || !signature_algorithms_cnt) { error_print(); return -1; } - if (x509_certs_get_last(cert_chain, cert_chain_len, &cert, &certlen) != 1) { + + if (prefered_sig_alg) { + *prefered_sig_alg = 0; + } + + if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, + &cert, &certlen) != 1) { error_print(); return -1; } - if ((ret = tls_authorities_issued_certificate(certificate_authorities, - certificate_authorities_len, cert, certlen)) < 0) { + + // signature_algorithms + if ((ret = tls_cert_match_signature_algorithms(cert, certlen, + signature_algorithms, signature_algorithms_cnt, &sig_alg)) < 0) { error_print(); return -1; } else if (ret == 0) { return 0; } - return 1; -} -int tls_cert_chain_match_client_hello_exts( - const uint8_t *cert_chain, size_t cert_chain_len, - const int *signature_algorithms, size_t signature_algorithms_cnt, - const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt, // optional - const uint8_t *host_name, size_t host_name_len) // optional -{ - const uint8_t *entity_cert; - size_t entity_cert_len; - int sig_alg; // the sig_alg is chosen by server, client's prefered sig_alg is no use - - if (!cert_chain || !cert_chain_len || !signature_algorithms || !signature_algorithms_cnt) { - error_print(); - return -1; - } - - if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &entity_cert, &entity_cert_len) != 1) { - error_print(); - return -1; - } - - if (tls_cert_match_signature_algorithms(entity_cert, entity_cert_len, - signature_algorithms, signature_algorithms_cnt, &sig_alg) != 1) { - error_print(); - return -1; - } + // server_name if (host_name && host_name_len) { - if (tls_cert_match_server_name(entity_cert, entity_cert_len, - host_name, host_name_len) != 1) { - error_print(); - return -1; - } - } - if (signature_algorithms_cert && signature_algorithms_cert_cnt) { - if (tls_cert_chain_match_signature_algorithms_cert(cert_chain, cert_chain_len, - signature_algorithms_cert, signature_algorithms_cert_cnt) != 1) { + if ((ret = tls_cert_match_server_name(cert, certlen, + host_name, host_name_len)) < 0) { error_print(); return -1; + } else if (ret == 0) { + return 0; } } + // signature_algorithms_cert + if (signature_algorithms_cert && signature_algorithms_cert_cnt) { + if ((ret = tls_cert_chain_match_signature_algorithms_cert(cert_chain, cert_chain_len, + signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) { + error_print(); + return -1; + } else if (ret == 0) { + return 0; + } + } + + // certificate_authorities + if (ca_names && ca_names_len) { + if ((ret = tls_authorities_issued_certificate( + ca_names, ca_names_len, cert, certlen)) < 0) { + error_print(); + return -1; + } else if (ret == 0) { + return 0; + } + } + + // oid_filters + if (oid_filters && oid_filters_len) { + } + + if (prefered_sig_alg) { + *prefered_sig_alg = sig_alg; + } return 1; } -int tls13_server_cert_chains_select(const uint8_t *cert_chains, size_t cert_chains_len, +int tls13_cert_chains_select(const uint8_t *cert_chains, size_t cert_chains_len, const int *signature_algorithms, size_t signature_algorithms_cnt, const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt, // optional - const uint8_t *host_name, size_t host_name_len, // optional - const uint8_t **certs, size_t *certs_len, int *certs_idx, int *prefered_sig_alg) // optional + const uint8_t *ca_names, size_t ca_names_len, // certificate_authorities optional + const uint8_t *oid_filters, size_t oid_filters_len, // optional, only in CertificateRequest + const uint8_t *host_name, size_t host_name_len, // optional, only in ClientHello + const uint8_t **certs, size_t *certs_len, size_t *certs_idx, int *prefered_sig_alg) // optional { - int ret; size_t i; - if (!cert_chains || !cert_chains_len || !signature_algorithms || !signature_algorithms_cnt) { + if (!cert_chains || !cert_chains_len + || !signature_algorithms || !signature_algorithms_cnt) { error_print(); return -1; } - for (i = 0; cert_chains_len; i++) { + for (i = 1; cert_chains_len; i++) { const uint8_t *cert_chain; size_t cert_chain_len; - const uint8_t *entity_cert; - size_t entity_cert_len; int sig_alg; + int ret; - if (tls_uint24array_from_bytes(&cert_chain, &cert_chain_len, &cert_chains, &cert_chains_len) != 1 - || x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &entity_cert, &entity_cert_len) != 1) { + if (tls_uint24array_from_bytes(&cert_chain, &cert_chain_len, + &cert_chains, &cert_chains_len) != 1) { error_print(); return -1; } - // entity_cert match signature_algorithms - if ((ret = tls_cert_match_signature_algorithms(entity_cert, entity_cert_len, - signature_algorithms, signature_algorithms_cnt, &sig_alg)) < 0) { + if ((ret = tls_cert_chain_match_extensions(cert_chain, cert_chain_len, + signature_algorithms, signature_algorithms_cnt, + signature_algorithms_cert, signature_algorithms_cert_cnt, + ca_names, ca_names_len, + oid_filters, oid_filters_len, + host_name, host_name_len, + &sig_alg)) < 0) { error_print(); return -1; } else if (ret == 0) { continue; } - // entity_cert match server_name (SNI) - if (host_name && host_name_len) { - if ((ret = tls_cert_match_server_name(entity_cert, entity_cert_len, - host_name, host_name_len)) < 0) { - error_print(); - return -1; - } else if (ret == 0) { - continue; - } - } - - // cert_chain match signature_algorithms_cert - if (signature_algorithms_cert && signature_algorithms_cert_cnt) { - if ((ret = tls_cert_chain_match_signature_algorithms_cert(cert_chain, cert_chain_len, - signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) { - error_print(); - return -1; - } else if (ret == 0) { - continue; - } - } - if (certs) *certs = cert_chain; if (certs_len) *certs_len = cert_chain_len; if (certs_idx) *certs_idx = i; if (prefered_sig_alg) *prefered_sig_alg = sig_alg; - return 1; } if (certs) *certs = NULL; if (certs_len) *certs_len = 0; - if (certs_idx) *certs_idx = -1; // -1 is valid value? + if (certs_idx) *certs_idx = 0; if (prefered_sig_alg) *prefered_sig_alg = 0; - + warning_print(); return 0; } -int tls13_client_cert_chains_select(const uint8_t *cert_chains, size_t cert_chains_len, - const int *signature_algorithms, size_t signature_algorithms_cnt, - const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt, // optional - const uint8_t *certificate_authorities, size_t certificate_authorities_len, // optional - const uint8_t **certs, size_t *certs_len, int *certs_idx, int *prefered_sig_alg) // optional -{ - int ret; - X509_KEY subject_public_key; - int sig_algs[16]; - int sig_alg; - size_t i; - - if (!cert_chains || !cert_chains_len || !signature_algorithms || !certs || !certs_len) { - error_print(); - return -1; - } - - if (!signature_algorithms_cnt) { - if (certs) *certs = NULL; - if (certs_len) *certs_len = 0; - if (certs_idx) *certs_idx = -1; - if (prefered_sig_alg) *prefered_sig_alg = 0; - return 0; - } - if (signature_algorithms_cert && !signature_algorithms_cert_cnt) { - if (certs) *certs = NULL; - if (certs_len) *certs_len = 0; - if (certs_idx) *certs_idx = -1; - if (prefered_sig_alg) *prefered_sig_alg = 0; - return 0; - } - - // prepare signature_algorithms oid - if (signature_algorithms_cnt > sizeof(sig_algs)/sizeof(sig_algs[0])) { - error_print(); - return -1; - } - for (i = 0; i < signature_algorithms_cnt; i++) { - if (!(sig_algs[i] = tls_signature_scheme_algorithm_oid(signature_algorithms[i]))) { - error_print(); - return -1; - } - } - - for (i = 0; cert_chains_len; i++) { - const uint8_t *cert_chain; - size_t cert_chain_len; - const uint8_t *cert; - size_t certlen; - - if (tls_uint24array_from_bytes(&cert_chain, &cert_chain_len, &cert_chains, &cert_chains_len) != 1) { - error_print(); - return -1; - } - - // check first cert's public key match signature_algorithms - if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1 - || x509_cert_get_subject_public_key(cert, certlen, &subject_public_key) != 1 - || x509_key_get_sign_algor(&subject_public_key, &sig_alg) != 1) { - error_print(); - return -1; - } - if (!tls_type_is_in_list(sig_alg, sig_algs, signature_algorithms_cnt)) { - continue; - } - - // check cert_chain match signature_algorithms_cert - if (signature_algorithms_cert) { - if ((ret = tls_cert_chain_match_signature_algorithms_cert(cert_chain, cert_chain_len, - signature_algorithms_cert, signature_algorithms_cert_cnt)) < 0) { - error_print(); - return -1; - } else if (ret == 0) { - continue; - } - } - - // check issuer of last cert in certificate_authorities - if (certificate_authorities) { - if (x509_certs_get_last(cert_chain, cert_chain_len, &cert, &certlen) != 1) { - error_print(); - return -1; - } - if ((ret = tls_authorities_issued_certificate(certificate_authorities, - certificate_authorities_len, cert, certlen)) < 0) { - error_print(); - return -1; - } else if (ret == 0) { - continue; - } - } - - if (certs) *certs = cert_chain; - if (certs_len) *certs_len = cert_chain_len; - if (certs_idx) *certs_idx = i; - if (prefered_sig_alg) *prefered_sig_alg = sig_alg; - - return 1; - } - - if (certs) *certs = NULL; - if (certs_len) *certs_len = 0; - if (certs_idx) *certs_idx = -1; - if (prefered_sig_alg) *prefered_sig_alg = 0; - - return 0; -} int tls13_recv_certificate_request(TLS_CONNECT *conn) { @@ -5051,6 +5196,7 @@ int tls13_recv_certificate_request(TLS_CONNECT *conn) int handshake_type; const uint8_t *handshake_data; size_t handshake_datalen; + int client_cert; // certificate_request const uint8_t *request_context; @@ -5067,11 +5213,17 @@ int tls13_recv_certificate_request(TLS_CONNECT *conn) size_t certificate_authorities_len; const uint8_t *oid_filters = NULL; size_t oid_filters_len; + int status_request = 0; + int signed_certificate_timestamp = 0; int common_sig_algs[4]; size_t common_sig_algs_cnt; int common_sig_algs_cert[4]; size_t common_sig_algs_cert_cnt; + const uint8_t *ca_names = NULL; + size_t ca_names_len = 0; + const uint8_t *filters = NULL; + size_t filters_len = 0; tls_trace("recv {CertificateRequest*}\n"); @@ -5089,6 +5241,7 @@ int tls13_recv_certificate_request(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_bad_record_mac); return -1; } + tls_seq_num_incr(conn->server_seq_num); if (tls_record_get_handshake(conn->plain_record, &handshake_type, &handshake_data, &handshake_datalen) != 1) { @@ -5096,25 +5249,18 @@ int tls13_recv_certificate_request(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_decode_error); return -1; } - if (handshake_type == TLS_handshake_certificate) { + if (handshake_type != TLS_handshake_certificate_request) { tls_trace(" no {CertificateRequest}\n"); return 0; } - tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); - if ((ret = tls13_record_get_handshake_certificate_request(conn->plain_record, - &request_context, &request_context_len, &exts, &extslen)) < 0) { + &request_context, &request_context_len, &exts, &extslen)) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_decode_error); return -1; - } else if (ret == 0) { - error_print(); - tls13_send_alert(conn, TLS_alert_unexpected_message); - return 0; } - if (request_context) { // request_context must be null in full/initial handshake // and must not be null in post authentication handshakes @@ -5134,6 +5280,14 @@ int tls13_recv_certificate_request(TLS_CONNECT *conn) return -1; } + // exts in CR (from RFC 8446 page 37) + // * signature_algorithms - the only ext must exist + // * signature_algorithms_cert + // * certificate_authorities + // * oid_filters (only in CR) + // * status_request + // * signed_certificate_timestamp + switch (ext_type) { case TLS_extension_signature_algorithms: case TLS_extension_signature_algorithms_cert: @@ -5141,8 +5295,18 @@ int tls13_recv_certificate_request(TLS_CONNECT *conn) case TLS_extension_oid_filters: if (!ext_data) { error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } + break; + case TLS_extension_status_request: + case TLS_extension_signed_certificate_timestamp: + if (ext_data) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + break; } switch (ext_type) { @@ -5186,67 +5350,121 @@ int tls13_recv_certificate_request(TLS_CONNECT *conn) oid_filters_len = ext_datalen; break; + case TLS_extension_status_request: + if (status_request) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + status_request = 1; + break; + + case TLS_extension_signed_certificate_timestamp: + if (signed_certificate_timestamp) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + signed_certificate_timestamp = 1; + break; + default: error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } } - ret = 1; - - // local cert_chain - if (!conn->ctx->cert_chains_len) { - ret = 0; - } - - // signature_algorithms if (!signature_algorithms) { error_print(); tls13_send_alert(conn, TLS_alert_missing_extension); return -1; } - if (tls_process_signature_algorithms(signature_algorithms, signature_algorithms_len, + + // even if no client cert, check extensions + if (conn->ctx->cert_chains_len) { + client_cert = 1; + } + + // signature_algorithms + if ((ret = tls_process_signature_algorithms( + signature_algorithms, signature_algorithms_len, conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, common_sig_algs, &common_sig_algs_cnt, - sizeof(common_sig_algs)/sizeof(common_sig_algs[0])) < 0) { + sizeof(common_sig_algs)/sizeof(common_sig_algs[0]))) < 0) { error_print(); return -1; - } - if (!common_sig_algs_cnt) { - ret = 0; + } else if (ret == 0) { + client_cert = 0; } // signature_algorithms_cert if (signature_algorithms_cert) { - if (tls_process_signature_algorithms(signature_algorithms_cert, signature_algorithms_cert_len, + if ((ret = tls_process_signature_algorithms( + signature_algorithms_cert, signature_algorithms_cert_len, conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, common_sig_algs_cert, &common_sig_algs_cert_cnt, - sizeof(common_sig_algs_cert)/sizeof(common_sig_algs_cert[0])) < 0) { + sizeof(common_sig_algs_cert)/sizeof(common_sig_algs_cert[0]))) < 0) { error_print(); return -1; - } - if (!common_sig_algs_cert_cnt) { - ret = 0; + } else if (ret == 0) { + client_cert = 0; } } - if (ret) { - // 如果没有找到合适的证书应该怎么处理 - if ((ret = tls13_client_cert_chains_select(conn->ctx->cert_chains, conn->ctx->cert_chains_len, + // certificate_authorities + if (certificate_authorities) { + if (tls13_certificate_authorities_from_bytes( + &ca_names, &ca_names_len, + certificate_authorities, certificate_authorities_len) != 1) { + error_print(); + return -1; + } + } + + // oid_filters + if (oid_filters) { + if (tls13_oid_filters_from_bytes( + &filters, &filters_len, oid_filters, oid_filters_len) != 1) { + error_print(); + return -1; + } + } + + // status_request + if (status_request) { + conn->status_request = 1; + } + + // signed_certificate_timestamp + if (signed_certificate_timestamp) { + conn->signed_certificate_timestamp = 1; + } + + // select cert_chain + // * signature_algorithms + // * [signature_algorithms_cert] + // * [certificate_authorities] + // * [oid_filter] + // + if (client_cert) { + if ((ret = tls13_cert_chains_select(conn->ctx->cert_chains, conn->ctx->cert_chains_len, common_sig_algs, common_sig_algs_cnt, common_sig_algs_cert, common_sig_algs_cert_cnt, - certificate_authorities, certificate_authorities_len, + ca_names, ca_names_len, + filters, filters_len, + NULL, 0, &conn->cert_chain, &conn->cert_chain_len, &conn->cert_chain_idx, &conn->sig_alg)) < 0) { error_print(); return -1; } + // when ret == 0, conn->cert_chain == NULL } if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { error_print(); return -1; } - tls_seq_num_incr(conn->server_seq_num); conn->certificate_request = 1; @@ -5258,19 +5476,21 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn) int ret; const uint8_t *request_context; size_t request_context_len; - const uint8_t *entity_status_request_ocsp_response; - size_t entity_status_request_ocsp_response_len; - const uint8_t *entity_signed_certificate_timestamp; - size_t entity_signed_certificate_timestamp_len; - const uint8_t *cert; - size_t certlen; - /* - const uint8_t *cp; - size_t len = 0; - int i; - */ + const uint8_t *leaf_status_request_ocsp_response; + size_t leaf_status_request_ocsp_response_len; + const uint8_t *leaf_signed_certificate_timestamp; + size_t leaf_signed_certificate_timestamp_len; - tls_trace("recv {Certificate}\n"); + const int *signature_algorithms_cert = NULL; + size_t signature_algorithms_cert_cnt = 0; + const uint8_t *ca_names = NULL; + size_t ca_names_len = 0; + const uint8_t *host_name = NULL; + size_t host_name_len = 0; + + int verify_result; + + tls_trace("recv server {Certificate}\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { @@ -5288,14 +5508,22 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_bad_record_mac); return -1; } + tls_seq_num_incr(conn->server_seq_num); + + } + + if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + error_print(); + return -1; } tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + tls_handshake_digest_print(stderr, 0, 0, "ServerCertificate", &conn->dgst_ctx); if ((ret = tls13_record_get_handshake_certificate(conn->plain_record, &request_context, &request_context_len, conn->peer_cert_chain, &conn->peer_cert_chain_len, sizeof(conn->peer_cert_chain), - &entity_status_request_ocsp_response, &entity_status_request_ocsp_response_len, - &entity_signed_certificate_timestamp, &entity_signed_certificate_timestamp_len)) < 0) { + &leaf_status_request_ocsp_response, &leaf_status_request_ocsp_response_len, + &leaf_signed_certificate_timestamp, &leaf_signed_certificate_timestamp_len)) < 0) { error_print(); tls13_send_alert(conn, TLS_alert_decode_error); return -1; @@ -5305,10 +5533,6 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn) return 0; } - // 我知道这里的问题了,我们在记录对方的证书链的时候,就是一个DER的序列 - - //error_print(); - if (request_context) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); @@ -5320,52 +5544,66 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn) return -1; } - // check entity cert extensions - if (entity_status_request_ocsp_response) { - if (ocsp_response_verify(entity_status_request_ocsp_response, entity_status_request_ocsp_response_len, + // check server cert_chain match ClientHello.extensions + if (conn->signature_algorithms_cert) { + signature_algorithms_cert = conn->ctx->signature_algorithms; + signature_algorithms_cert_cnt = conn->ctx->signature_algorithms_cnt; + } + if (conn->certificate_authorities) { + ca_names = conn->ctx->ca_names; + ca_names_len = conn->ctx->ca_names_len; + } + if (conn->server_name) { + host_name = conn->host_name; + host_name_len = conn->host_name_len; + } + if (tls_cert_chain_match_extensions(conn->peer_cert_chain, conn->peer_cert_chain_len, + conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, + signature_algorithms_cert, signature_algorithms_cert_cnt, + ca_names, ca_names_len, // certificate_authorities + NULL, 0, // oid_filters + host_name, host_name_len, + NULL) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + + // verify server cert_chain + if (x509_certs_verify( + conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, + conn->ctx->cacerts, conn->ctx->cacertslen, + conn->ctx->verify_depth, &verify_result) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } + // status_request + if (leaf_status_request_ocsp_response) { + if (ocsp_response_verify( + leaf_status_request_ocsp_response, + leaf_status_request_ocsp_response_len, conn->ctx->cacerts, conn->ctx->cacertslen) != 1) { error_print(); + tls13_send_alert(conn, TLS_alert_certificate_revoked); return -1; } } - if (entity_signed_certificate_timestamp) { - // TODO: check + // signed_certificate_timestamp + if (leaf_signed_certificate_timestamp) { + if (tls13_signed_certificate_timestamp_verify( + leaf_signed_certificate_timestamp, + leaf_signed_certificate_timestamp_len) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } } - - //error_print(); - - // check extensions matching - if (tls_cert_chain_match_client_hello_exts( - conn->peer_cert_chain, conn->peer_cert_chain_len, - conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, - conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, - conn->host_name, conn->host_name_len) != 1) { - error_print(); - tls13_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - - //error_print(); - - int verify_result; - if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, - conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) { - error_print(); - tls13_send_alert(conn, TLS_alert_bad_certificate); - return -1; - } - - if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { - error_print(); - return -1; - } - tls_seq_num_incr(conn->server_seq_num); - return 1; } -int tls13_recv_certificate_verify(TLS_CONNECT *conn) +int tls13_recv_server_certificate_verify(TLS_CONNECT *conn) { int ret; int sig_alg; @@ -5375,7 +5613,7 @@ int tls13_recv_certificate_verify(TLS_CONNECT *conn) size_t certlen; X509_KEY public_key; - tls_trace("recv {CertificateVerify}\n"); + tls_trace("recv server {CertificateVerify}\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { @@ -5391,6 +5629,7 @@ int tls13_recv_certificate_verify(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_bad_record_mac); return -1; } + tls_seq_num_incr(conn->server_seq_num); tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); if ((ret = tls13_record_get_handshake_certificate_verify(conn->plain_record, @@ -5433,11 +5672,97 @@ int tls13_recv_certificate_verify(TLS_CONNECT *conn) error_print(); return -1; } - tls_seq_num_incr(conn->server_seq_num); return 1; } +int tls13_recv_client_certificate_verify(TLS_CONNECT *conn) +{ + int ret; + int sig_alg; + const uint8_t *sig; + size_t siglen; + const uint8_t *cert; + size_t certlen; + X509_KEY public_key; + + tls_trace("recv client {CertificateVerify}\n"); + + if ((ret = tls_recv_record(conn)) != 1) { + if (ret != TLS_ERROR_RECV_AGAIN) { + error_print(); + } + return ret; + } + + 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(); + tls13_send_alert(conn, TLS_alert_bad_record_mac); + return -1; + } + tls_seq_num_incr(conn->client_seq_num); + 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(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + error_print(); + tls13_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + if (tls_type_is_in_list(sig_alg, conn->ctx->signature_algorithms, + conn->ctx->signature_algorithms_cnt) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + if (!sig) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + + if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 0, &cert, &certlen) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_unexpected_message); + return -1; + } + + // verify signature + if (tls13_verify_certificate_verify(TLS_server_mode, sig_alg, &public_key, + &conn->dgst_ctx, sig, siglen) != 1) { + error_print(); + return -1; + } + + if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { + error_print(); + return -1; + } + + return 1; +} + + + + + + + + + + + + + + + int tls13_recv_server_finished(TLS_CONNECT *conn) { int ret; @@ -5455,7 +5780,7 @@ int tls13_recv_server_finished(TLS_CONNECT *conn) return -1; } - tls_trace("recv {Finished}\n"); + tls_trace("recv server {Finished}\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { error_print(); @@ -5470,12 +5795,14 @@ int tls13_recv_server_finished(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_bad_record_mac); return -1; } + tls_seq_num_incr(conn->server_seq_num); tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { error_print(); return -1; } - tls_seq_num_incr(conn->server_seq_num); + tls_handshake_digest_print(stderr, 0, 0, "ServerFinished", &conn->dgst_ctx); + if ((ret = tls13_record_get_handshake_finished(conn->plain_record, &server_verify_data, &server_verify_data_len)) < 0) { @@ -5521,20 +5848,32 @@ int tls13_send_client_certificate(TLS_CONNECT *conn) { int ret; - tls_trace("send {Certificate*}\n"); + tls_trace("send {Certificate}\n"); - if (!conn->recordlen) { - size_t padding_len; - uint8_t *request_context = NULL; + if (conn->recordlen == 0) { + const uint8_t *request_context = NULL; size_t request_context_len = 0; - uint8_t *entity_status_request_ocsp_response = NULL; + const uint8_t *entity_status_request_ocsp_response = NULL; size_t entity_status_request_ocsp_response_len = 0; - uint8_t *entity_signed_certificate_timestamp = NULL; + const uint8_t *entity_signed_certificate_timestamp = NULL; size_t entity_signed_certificate_timestamp_len = 0; + size_t padding_len; + + // status_request + if (conn->status_request) { + entity_status_request_ocsp_response = conn->status_request_ocsp_response; + entity_status_request_ocsp_response_len = conn->status_request_ocsp_response_len; + } + + // signed_certificate_timestamp + if (conn->signed_certificate_timestamp) { + entity_signed_certificate_timestamp = conn->signed_certificate_timestamp_list; + entity_signed_certificate_timestamp_len = conn->signed_certificate_timestamp_list_len; + } if (tls13_record_set_handshake_certificate(conn->plain_record, &conn->plain_recordlen, request_context, request_context_len, - conn->client_certs, conn->client_certs_len, + conn->cert_chain, conn->cert_chain_len, entity_status_request_ocsp_response, entity_status_request_ocsp_response_len, entity_signed_certificate_timestamp, entity_signed_certificate_timestamp_len) != 1) { error_print(); @@ -5548,8 +5887,6 @@ int tls13_send_client_certificate(TLS_CONNECT *conn) return -1; } - format_bytes(stderr, 0, 0, "client_seq_num", conn->client_seq_num, 8); - 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, @@ -5566,44 +5903,23 @@ int tls13_send_client_certificate(TLS_CONNECT *conn) } return ret; } + return 1; } -// 为什么要有一个单独的send_client_certificate_verify int tls13_send_client_certificate_verify(TLS_CONNECT *conn) { int ret; - - // 这里需要一个单独的处理,因此需要单独的 - if (conn->is_client && !conn->cert_chain) { - tls_trace("omit {CertificateVerify*}\n"); - return 0; - } - tls_trace("send {CertificateVerify*}\n"); if (!conn->recordlen) { - X509_KEY *sign_key = &conn->ctx->x509_keys[conn->cert_chain_idx]; - int sig_alg = 0; + X509_KEY *sign_key = &conn->ctx->x509_keys[conn->cert_chain_idx - 1]; uint8_t sig[256]; size_t siglen; size_t padding_len; - size_t i; - // use the first matching sig_alg - for (i = 0; i < conn->ctx->signature_algorithms_cnt; i++) { - if (tls_signature_scheme_group_oid(conn->ctx->signature_algorithms[i]) == sign_key->algor_param) { - sig_alg = conn->ctx->signature_algorithms[i]; - break; - } - } - if (!sig_alg) { - error_print(); - return -1; - } - - if (tls13_sign_certificate_verify(TLS_client_mode, sig_alg, + if (tls13_sign_certificate_verify(TLS_client_mode, conn->sig_alg, sign_key, &conn->dgst_ctx, sig, &siglen) != 1) { error_print(); return -1; @@ -5611,7 +5927,7 @@ int tls13_send_client_certificate_verify(TLS_CONNECT *conn) if (tls13_record_set_handshake_certificate_verify( conn->plain_record, &conn->plain_recordlen, - sig_alg, sig, siglen) != 1) { + conn->sig_alg, sig, siglen) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_internal_error); return -1; @@ -5641,8 +5957,6 @@ int tls13_send_client_certificate_verify(TLS_CONNECT *conn) return ret; } - tls_seq_num_incr(conn->client_seq_num); - return 1; } @@ -5651,16 +5965,22 @@ int tls13_send_client_finished(TLS_CONNECT *conn) int ret; uint8_t client_write_key[16]; - tls_trace("send {Finished}\n"); + tls_trace("send client {Finished}\n"); if (!conn->recordlen) { uint8_t verify_data[64]; size_t verify_data_len; size_t padding_len; + + tls_handshake_digest_print(stderr, 0, 0, "before ClientFinished", &conn->dgst_ctx); + tls13_compute_verify_data(conn->client_handshake_traffic_secret, &conn->dgst_ctx, verify_data, &verify_data_len); + memset(&conn->dgst_ctx, 0, sizeof(conn->dgst_ctx)); + + if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen, verify_data, verify_data_len) != 1) { error_print(); @@ -5669,10 +5989,8 @@ int tls13_send_client_finished(TLS_CONNECT *conn) } tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); - if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { - error_print(); - return -1; - } + + format_bytes(stderr, 0, 0, "client_seq_num", conn->client_seq_num, 8); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->client_write_key, conn->client_write_iv, @@ -5682,6 +6000,7 @@ int tls13_send_client_finished(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_internal_error); return -1; } + tls_seq_num_incr(conn->client_seq_num); } @@ -5693,7 +6012,6 @@ int tls13_send_client_finished(TLS_CONNECT *conn) return ret; } - //update client_write_key, client_write_iv, reset client_seq_num tls13_hkdf_expand_label(conn->digest, conn->client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); tls13_hkdf_expand_label(conn->digest, conn->client_application_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); @@ -5711,13 +6029,6 @@ int tls13_send_client_finished(TLS_CONNECT *conn) } - - - - - - - int tls13_recv_client_hello(TLS_CONNECT *conn) { int ret; @@ -5749,6 +6060,8 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) 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 *key_share = NULL; size_t key_share_len; const uint8_t *server_name = NULL; @@ -5770,10 +6083,15 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) size_t common_sig_algs_cnt = 0; int common_sig_algs_cert[4]; size_t common_sig_algs_cert_cnt = 0; - int common_key_exchange_modes = 0; + const uint8_t *host_name = NULL; size_t host_name_len; + int common_key_exchange_modes = 0; + + const uint8_t *ca_names = NULL; + size_t ca_names_len = 0; + // 这个判断应该改为一个函数 /* @@ -5853,11 +6171,37 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_decode_error); return -1; } + + // exts in CH (RFC 8446 page 37), only oid_filter not in CH + // * supported_versions + // * signature_algorithms + // * signature_algorithms_cert + // * certificate_authorities + // * server_name + // * status_request + // * signed_certificate_timestamp + // * supported_groups + // * key_share + // * psk_key_exchange_modes + // * pre_shared_key + // * early_data (only in ClientHello1) + // * max_fragment_length + // * use_srtp + // * heartbeat + // * application_layer_protocol_negotiation + // * server_certificate_type: if client accept raw/x509 + // * client_certificate_type: if client sned raw/x509 + // * padding + // * post_handshake_auth: client support post handshake auth + // * cookie (only in ClientHello2) + + switch (ext_type) { case TLS_extension_supported_versions: case TLS_extension_supported_groups: case TLS_extension_signature_algorithms: case TLS_extension_signature_algorithms_cert: + case TLS_extension_certificate_authorities: case TLS_extension_key_share: case TLS_extension_server_name: case TLS_extension_psk_key_exchange_modes: @@ -5868,8 +6212,8 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) return -1; } break; - case TLS_extension_early_data: case TLS_extension_signed_certificate_timestamp: + case TLS_extension_early_data: if (ext_data) { error_print(); return -1; @@ -5918,6 +6262,16 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) signature_algorithms_cert_len = ext_datalen; break; + case TLS_extension_certificate_authorities: + if (certificate_authorities) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + certificate_authorities = ext_data; + certificate_authorities_len = ext_datalen; + break; + case TLS_extension_key_share: if (key_share) { error_print(); @@ -5986,17 +6340,57 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) early_data = 1; break; + 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_server_certificate_type: + case TLS_extension_client_certificate_type: + case TLS_extension_padding: + case TLS_extension_post_handshake_auth: + break; + + case TLS_extension_cookie: + error_print(); default: - warning_print(); + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; } } - // supported_versions + // from RFC 8446 section 9.2 + // * supported_versions required for CH, SH, HRR + // * if no pre_shared_key, signature_algorithms + supported_groups must exist + // * supported_groups + key_share must exist together + // * empty key_share is permitted + // if (!supported_versions) { error_print(); tls13_send_alert(conn, TLS_alert_missing_extension); return -1; } + if (!pre_shared_key) { + if (!(signature_algorithms && supported_groups)) { + error_print(); + tls13_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + } + if ((supported_groups && !key_share) + || (!supported_groups && key_share)) { + error_print(); + tls13_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + if ((psk_key_exchange_modes && !pre_shared_key) + || (!psk_key_exchange_modes && pre_shared_key)) { + error_print(); + tls13_send_alert(conn, TLS_alert_missing_extension); + return -1; + } + + // supported_versions if ((ret = tls13_process_client_supported_versions( supported_versions, supported_versions_len, conn->ctx->supported_versions, conn->ctx->supported_versions_cnt, @@ -6017,6 +6411,7 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) } conn->protocol = common_versions[0]; + // psk_key_exchange_modes if (psk_key_exchange_modes) { if (tls13_psk_key_exchange_modes_from_bytes(&common_key_exchange_modes, @@ -6025,132 +6420,89 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) return -1; } } + // client key_exchange_modes if (supported_groups && signature_algorithms) { common_key_exchange_modes |= TLS_KE_CERT_DHE; } - // the final common key_exchang_modes + // common key_exchange_modes common_key_exchange_modes &= conn->key_exchange_modes; - - // no common modes if (!common_key_exchange_modes) { error_print(); tls13_send_alert(conn, TLS_alert_handshake_failure); return -1; } - // supported_groups - if (supported_groups) { - if (common_key_exchange_modes & (TLS_KE_CERT_DHE|TLS_KE_PSK_DHE)) { - if (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(); - tls13_send_alert(conn, TLS_alert_decode_error); - return -1; - } - if (!common_groups_cnt) { - common_key_exchange_modes &= ~(TLS_KE_CERT_DHE|TLS_KE_PSK_DHE); - } - } - } - // signature_algorithms if (signature_algorithms) { - if (common_key_exchange_modes & TLS_KE_CERT_DHE) { - if (tls_process_signature_algorithms( - signature_algorithms, signature_algorithms_len, - conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, - common_sig_algs, &common_sig_algs_cnt, - sizeof(common_sig_algs)/sizeof(common_sig_algs[0])) < 0) { - error_print(); - tls13_send_alert(conn, TLS_alert_decode_error); - return -1; - } - if (!common_sig_algs_cnt) { - common_key_exchange_modes &= ~TLS_KE_CERT_DHE; - } + if ((ret = tls_process_signature_algorithms( + signature_algorithms, signature_algorithms_len, + conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, + common_sig_algs, &common_sig_algs_cnt, + sizeof(common_sig_algs)/sizeof(common_sig_algs[0]))) < 0) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + common_key_exchange_modes &= ~TLS_KE_CERT_DHE; } } // signature_algorithms_cert if (signature_algorithms_cert) { - if (common_key_exchange_modes & TLS_KE_CERT_DHE) { - if (tls_process_signature_algorithms( - signature_algorithms_cert, signature_algorithms_cert_len, - conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, - common_sig_algs_cert, &common_sig_algs_cert_cnt, - sizeof(common_sig_algs_cert)/sizeof(common_sig_algs_cert[0])) < 0) { - error_print(); - tls13_send_alert(conn, TLS_alert_decode_error); - return -1; - } - if (!common_sig_algs_cert_cnt) { - common_key_exchange_modes &= ~TLS_KE_CERT_DHE; - } + if ((ret = tls_process_signature_algorithms( + signature_algorithms_cert, signature_algorithms_cert_len, + conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, + common_sig_algs_cert, &common_sig_algs_cert_cnt, + sizeof(common_sig_algs_cert)/sizeof(common_sig_algs_cert[0]))) < 0) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + common_key_exchange_modes &= ~TLS_KE_CERT_DHE; } } - // key_share - if (key_share) { - if (common_key_exchange_modes & (TLS_KE_CERT_DHE|TLS_KE_PSK_DHE)) { - int group = 0; - const uint8_t *key_exchange = NULL; - size_t key_exchange_len = 0; - - if ((ret = tls13_process_key_share_client_hello( - key_share, key_share_len, - common_groups, common_groups_cnt, - &group, &key_exchange, &key_exchange_len)) < 0) { - error_print(); - tls13_send_alert(conn, TLS_alert_decode_error); - return -1; - } else if (ret == 0) { - // backup ClientHello1 for HelloRetryRequest 这个备份可能没有必要啊 - memcpy(conn->plain_record, conn->record, conn->recordlen); - conn->plain_recordlen = conn->recordlen; - conn->key_exchange_group = common_groups[0]; - - } else { - // valid key_exchange found - if (key_exchange_len != 65) { - error_print(); - return -1; - } - conn->key_exchange_group = group; - memcpy(conn->peer_key_exchange, key_exchange, key_exchange_len); - conn->peer_key_exchange_len = key_exchange_len; - } + // certificate_authorities + if (certificate_authorities) { + if (tls13_certificate_authorities_from_bytes(&ca_names, &ca_names_len, + certificate_authorities, certificate_authorities_len) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; } } // server_name if (server_name) { - if (tls_server_name_from_bytes(&host_name, &host_name_len, server_name, server_name_len) != 1) { + if (tls_server_name_from_bytes(&host_name, &host_name_len, + server_name, server_name_len) != 1) { error_print(); return -1; } + conn->server_name = 1; } // select server cert_chain // * signature_algorithms // * [signature_algorithms_cert] + // * [certificate_authorities] // * [server_name.host_name] - // * [oid_filter] // if (common_key_exchange_modes & TLS_KE_CERT_DHE) { - if (tls13_server_cert_chains_select(conn->ctx->cert_chains, conn->ctx->cert_chains_len, + if ((ret = tls13_cert_chains_select( + conn->ctx->cert_chains, conn->ctx->cert_chains_len, common_sig_algs, common_sig_algs_cnt, common_sig_algs_cert, common_sig_algs_cert_cnt, + ca_names, ca_names_len, + NULL, 0, // oid_filters host_name, host_name_len, - &conn->cert_chain, &conn->cert_chain_len, &conn->cert_chain_idx, &conn->sig_alg) < 0) { + &conn->cert_chain, &conn->cert_chain_len, &conn->cert_chain_idx, &conn->sig_alg)) < 0) { error_print(); tls13_send_alert(conn, TLS_alert_decode_error); return -1; - } - if (!conn->cert_chain) { + } else if (ret == 0) { + error_print(); common_key_exchange_modes &= ~TLS_KE_CERT_DHE; } } @@ -6163,45 +6515,129 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) const uint8_t *request_exts; size_t request_exts_len; - if (tls_client_status_request_from_bytes(&status_type, &responder_id_list, &responder_id_list_len, - &request_exts, &request_exts_len, status_request, status_request_len) != 1) { + if (tls_client_status_request_from_bytes(&status_type, + &responder_id_list, &responder_id_list_len, + &request_exts, &request_exts_len, + status_request, status_request_len) != 1) { error_print(); return -1; } + if (status_type != TLS_certificate_status_type_ocsp) { + error_print(); + return -1; + } + if (conn->cert_chain) { + const uint8_t *cp = conn->ctx->status_request_ocsp_responses; + size_t len = conn->ctx->status_request_ocsp_responses_len; + size_t i; - if (status_type == TLS_certificate_status_type_ocsp) { - if ((conn->status_request = tls_ocsp_response_match_status_request( - conn->status_request_ocsp_response, conn->status_request_ocsp_response_len, - responder_id_list, responder_id_list_len, request_exts, request_exts_len)) < 0) { + // get ocsp_response + for (i = 0; i < conn->cert_chain_idx; i++) { + if (tls_uint24array_from_bytes( + &conn->status_request_ocsp_response, + &conn->status_request_ocsp_response_len, + &cp, &len) != 1) { + error_print(); + return -1; + } + } + // check if ocsp_response match the status_request + if (conn->status_request_ocsp_response) { + if ((ret = tls_ocsp_response_match_status_request( + conn->status_request_ocsp_response, + conn->status_request_ocsp_response_len, + responder_id_list, responder_id_list_len, + request_exts, request_exts_len)) < 0) { + error_print(); + return -1; + } else if (ret == 0) { + conn->status_request_ocsp_response = NULL; + conn->status_request_ocsp_response_len = 0; + } + } + } + // send CertificateRequest.status_request + conn->status_request = 1; + } + + // signed_certificate_timestamp + if (signed_certificate_timestamp) { + if (conn->cert_chain) { + const uint8_t *sct_lists = conn->ctx->signed_certificate_timestamp_lists; + size_t sct_lists_len = conn->ctx->signed_certificate_timestamp_lists_len; + size_t i; + + for (i = 0; i < conn->cert_chain_idx; i++) { + if (tls_uint16array_from_bytes( + &conn->signed_certificate_timestamp_list, + &conn->signed_certificate_timestamp_list_len, + &sct_lists, &sct_lists_len) != 1) { + error_print(); + return -1; + } + } + } + // send CertificateRequest.signed_certificate_timestamp + conn->signed_certificate_timestamp = 1; + } + + // supported_groups + if (supported_groups) { + 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(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } else if (ret == 0) { + common_key_exchange_modes &= ~(TLS_KE_CERT_DHE|TLS_KE_PSK_DHE); + } + } + + // key_share + if (key_share) { + int group = 0; + const uint8_t *key_exchange = NULL; + size_t key_exchange_len = 0; + + if (common_groups_cnt) { + if ((ret = tls13_process_key_share_client_hello( + key_share, key_share_len, common_groups, common_groups_cnt, + &group, &key_exchange, &key_exchange_len)) < 0) { error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); return -1; + } else if (ret == 0) { + // send HelloRetryRequest if modes == CERT_DHE|PSK_DHE + conn->key_exchange_group = common_groups[0]; + } else { + conn->key_exchange_group = group; + memcpy(conn->peer_key_exchange, key_exchange, key_exchange_len); + conn->peer_key_exchange_len = key_exchange_len; } } } - // SCT - if (signed_certificate_timestamp) { - - } - - // pre_shared_key if (pre_shared_key) { if (common_key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) { - - int psk_selected = 0; - if (conn->psk_identities_len) { - if ((psk_selected = tls13_process_client_pre_shared_key_external(conn, + if ((ret = tls13_process_client_pre_shared_key_external(conn, pre_shared_key, pre_shared_key_len)) < 0) { error_print(); return -1; + } else if (ret == 0) { + common_key_exchange_modes &= ~(TLS_KE_PSK_DHE|TLS_KE_PSK); } } else if (conn->ctx->session_ticket_key) { - if ((psk_selected = tls13_process_client_pre_shared_key_from_ticket(conn, + if ((ret = tls13_process_client_pre_shared_key_from_ticket(conn, pre_shared_key, pre_shared_key_len)) < 0) { error_print(); return -1; + } else if (ret == 0) { + common_key_exchange_modes &= ~(TLS_KE_PSK_DHE|TLS_KE_PSK); } } else { // caller should set session_ticket_key or psk_keys @@ -6209,15 +6645,8 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) return -1; } - // update psk_key_exchange_modes - if (!psk_selected) { - common_key_exchange_modes &= ~(TLS_KE_PSK_DHE|TLS_KE_PSK); - format_print(stderr, 0, 0, "no common pre_shared_key\n"); - } else { - conn->pre_shared_key = 1; - format_print(stderr, 0, 0, "selected_psk_identity: %d\n", conn->selected_psk_identity - 1); - format_bytes(stderr, 0, 0, "selected_psk", conn->psk, conn->psk_len); - } + //format_print(stderr, 0, 0, "selected_psk_identity: %d\n", conn->selected_psk_identity - 1); + //format_bytes(stderr, 0, 0, "selected_psk", conn->psk, conn->psk_len); } } @@ -6240,7 +6669,7 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) if (common_key_exchange_modes & TLS_KE_PSK_DHE) { if (conn->selected_psk_identity && conn->key_exchange_group) { conn->key_exchange_modes = TLS_KE_PSK_DHE; - if (!conn->key_exchanges_cnt) { + if (!conn->peer_key_exchange_len) { conn->hello_retry_request = 1; } } @@ -6261,14 +6690,18 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) return -1; } - tls_key_exchange_modes_print(stderr, 0, 0, ">>>> key_exchange_modes", conn->key_exchange_modes); - + //tls_key_exchange_modes_print(stderr, 0, 0, ">>>> key_exchange_modes", conn->key_exchange_modes); // hello_retry_request if (conn->hello_retry_request) { uint8_t message_hash[4 + 32]; size_t dgstlen; + // cache ClientHello1, need by recv_client_hello_again + memcpy(conn->plain_record, conn->record, conn->recordlen); + conn->plain_recordlen = conn->recordlen; + + // message_hash handshake message_hash[0] = TLS_handshake_message_hash; message_hash[1] = 0; @@ -6292,6 +6725,7 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) error_print(); return -1; } + tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); } // early_data @@ -6303,33 +6737,10 @@ int tls13_recv_client_hello(TLS_CONNECT *conn) // generate early_data keys if (conn->early_data) { - - /* - uint8_t zeros[32] = {0}; - uint8_t early_secret[32]; - uint8_t client_early_traffic_secret[32]; - uint8_t client_write_key[16]; - - // [1] - tls13_hkdf_extract(conn->digest, zeros, conn->psk, early_secret); - // [2] - tls13_derive_secret(early_secret, "c e traffic", &conn->dgst_ctx, client_early_traffic_secret); - tls13_hkdf_expand_label(conn->digest, client_early_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, client_early_traffic_secret, "iv", NULL, 0, 12, conn->client_write_iv); - tls_seq_num_reset(conn->client_seq_num); - - format_print(stderr, 0, 0, "client_write_key/iv <= client_early_traffic_secret\n"); - format_bytes(stderr, 0, 4, "client_early_traffic_secret", client_early_traffic_secret, 32); - 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); - */ - if (tls13_generate_early_data_keys(conn) != 1) { error_print(); return -1; } - } if (client_verify) @@ -6347,8 +6758,11 @@ int tls13_send_hello_retry_request(TLS_CONNECT *conn) tls_trace("send HelloRetryRequest\n"); if (conn->recordlen == 0) { + const uint8_t *legacy_session_id_echo = NULL; + size_t legacy_session_id_echo_len = 0; + int legacy_compress_meth = 0; uint8_t exts[256]; - uint8_t *p = exts; + uint8_t *pexts = exts; size_t extslen = 0; int curve_oid; uint8_t cookie[256]; @@ -6356,38 +6770,60 @@ int tls13_send_hello_retry_request(TLS_CONNECT *conn) tls_record_set_protocol(conn->record, TLS_protocol_tls12); - if (rand_bytes(conn->server_random, 32) != 1) { + if (tls13_random_generate(conn->server_random) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_internal_error); return -1; } - 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) { + if (conn->session_id_len) { + legacy_session_id_echo = conn->session_id; + legacy_session_id_echo_len = conn->session_id_len; + } + + // exts in HRR + // * supported_versions + // * key_share + // * [cookie] + + // supported_versions + if (tls13_server_supported_versions_ext_to_bytes( + TLS_protocol_tls13, &pexts, &extslen) != 1) { error_print(); return -1; } + + // key_share + if (tls13_key_share_hello_retry_request_ext_to_bytes( + conn->key_exchange_group, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + + // cookie if (conn->cookie) { - if (tls13_cookie_generate(&conn->ctx->cookie_key, NULL, 0, cookie, &cookie_len) != 1) { + // TODO: cookie = {ClientHello} + if (tls13_cookie_generate(&conn->ctx->cookie_key, NULL, 0, + cookie, &cookie_len) != 1) { error_print(); return -1; } - if (tls13_cookie_ext_to_bytes(cookie, sizeof(cookie), &p, &extslen) != 1) { + if (tls13_cookie_ext_to_bytes( + cookie, sizeof(cookie), &pexts, &extslen) != 1) { error_print(); return -1; } } - int legacy_compress_meth = 0; - - if (tls13_record_set_handshake_hello_retry_request(conn->record, &conn->recordlen, - TLS_protocol_tls12, conn->server_random, NULL, 0, + if (tls13_record_set_handshake_hello_retry_request( + conn->record, &conn->recordlen, + TLS_protocol_tls12, conn->server_random, + legacy_session_id_echo, legacy_session_id_echo_len, conn->cipher_suite, legacy_compress_meth, exts, extslen) != 1) { error_print(); return -1; } tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); - } if ((ret = tls_send_record(conn)) != 1) { @@ -6407,8 +6843,6 @@ int tls13_send_hello_retry_request(TLS_CONNECT *conn) } tls_clean_record(conn); - return 1; - return 1; } @@ -6423,30 +6857,6 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn) int protocol; - // ClientHello2 - 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; - const uint8_t *supported_versions = NULL; - size_t supported_versions_len = 0; - const uint8_t *supported_groups = NULL; - size_t supported_groups_len = 0; - const uint8_t *key_share = NULL; - size_t key_share_len = 0; - const uint8_t *key_exchange = NULL; - size_t key_exchange_len = 0; - const uint8_t *signature_algorithms = NULL; - size_t signature_algorithms_len; - const uint8_t *cookie = NULL; - size_t cookie_len; - // ClientHello1 int _legacy_version; const uint8_t *_random; @@ -6458,12 +6868,30 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn) size_t _legacy_comp_methods_len; const uint8_t *_exts; size_t _extslen; - const uint8_t *_supported_versions = NULL; - size_t _supported_versions_len = 0; - const uint8_t *_supported_groups = NULL; - size_t _supported_groups_len = 0; - const uint8_t *_signature_algorithms = NULL; - size_t _signature_algorithms_len = 0; + + // ClientHello2 + 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 *key_share = NULL; + size_t key_share_len; + const uint8_t *pre_shared_key = NULL; + size_t pre_shared_key_len; + const uint8_t *cookie = NULL; + size_t cookie_len; + + const uint8_t *key_exchange; + size_t key_exchange_len; + tls_trace("recv ClientHello again\n"); @@ -6491,166 +6919,190 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_unexpected_message); return -1; } + if (legacy_version != TLS_protocol_tls12) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } // ClientHello1 if (tls_record_get_handshake_client_hello(conn->plain_record, &_legacy_version, &_random, &_legacy_session_id, &_legacy_session_id_len, &_cipher_suites, &_cipher_suites_len, &_exts, &_extslen) != 1) { error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); return -1; } - if (legacy_version != _legacy_version || legacy_session_id_len != _legacy_session_id_len || memcmp(legacy_session_id, _legacy_session_id, _legacy_session_id_len) != 0 || cipher_suites_len != _cipher_suites_len - || memcmp(cipher_suites, _cipher_suites, _cipher_suites_len) != 0 - //|| legacy_comp_methods_len != _legacy_comp_methods_len - //|| memcmp(legacy_comp_methods, _legacy_comp_methods, _legacy_comp_methods_len) != 0 - ) { + || memcmp(cipher_suites, _cipher_suites, _cipher_suites_len) != 0) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + // client random, should not send the same random + if (memcmp(random, conn->client_random, 32) == 0) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } - // update random - if (memcmp(random, _random, 32) == 0) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } + // update client_server memcpy(conn->client_random, random, 32); - // ClientHello1 extensions - 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(); - tls13_send_alert(conn, TLS_alert_decode_error); - return -1; - } - switch (_ext_type) { - case TLS_extension_supported_versions: - _supported_versions = _ext_data; - _supported_versions_len = _ext_datalen; - break; - case TLS_extension_supported_groups: - _supported_groups = _ext_data; - _supported_groups_len = _ext_datalen; - break; - case TLS_extension_signature_algorithms: - _signature_algorithms = _ext_data; - _signature_algorithms_len = _ext_datalen; - break; - } - } - - // process ClientHello2 extensions while (extslen) { int ext_type; const uint8_t *ext_data; size_t ext_datalen; + 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(); tls13_send_alert(conn, TLS_alert_decode_error); return -1; } - if (!ext_datalen) { + + // ClientHello2 extensions + // * key_share - must exist, only one key_exchange based on conn->key_exchange_group + // * pre_shared_key - might be subset of ClientHello1.pre_shared_key + // * early_data - must not exist + // * cookie - should exsit if conn->cookie == 1 + + // early_data must not in ClientHello2 + if (ext_type == TLS_extension_early_data) { error_print(); - tls13_send_alert(conn, TLS_alert_decode_error); + tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } - switch (ext_type) { - case TLS_extension_supported_versions: - if (supported_versions) { - error_print(); - return -1; - } - if (ext_datalen != _supported_versions_len - || memcmp(ext_data, _supported_versions, _supported_versions_len) != 0) { - error_print(); - return -1; - } - supported_versions = ext_data; - supported_versions_len = ext_datalen; - break; - - case TLS_extension_supported_groups: - if (supported_groups - || ext_datalen != _supported_groups_len - || memcmp(ext_data, _supported_groups, _supported_groups_len) != 0) { + // cookie not in ClientHello1 + if (ext_type == TLS_extension_cookie) { + if (!conn->cookie) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } - supported_groups = ext_data; - supported_groups_len = ext_datalen; - break; - - case TLS_extension_signature_algorithms: - if (signature_algorithms - || ext_datalen != _signature_algorithms_len - || memcmp(ext_data, _signature_algorithms, _signature_algorithms_len) != 0) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - signature_algorithms = ext_data; - signature_algorithms_len = ext_datalen; - break; - - case TLS_extension_key_share: - if (key_share) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; - } - key_share = ext_data; - key_share_len = ext_datalen; - break; - - case TLS_extension_cookie: - if (cookie) { + if (!ext_data) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } cookie = ext_data; cookie_len = ext_datalen; - break; + continue; + } - // ClientHello2 should not have early_data - case TLS_extension_early_data: + // get ext in ClientHello1 (omit early_data) + if (tls_ext_from_bytes(&_ext_type, &_ext_data, &_ext_datalen, &_exts, &_extslen) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } + if (_ext_type == TLS_extension_early_data) { + if (tls_ext_from_bytes(&_ext_type, &_ext_data, &_ext_datalen, &_exts, &_extslen) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } + } + if (ext_type != _ext_type) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } + + // check ext_data + switch (ext_type) { + case TLS_extension_key_share: + if (!ext_data) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } + key_share = ext_data; + key_share_len = ext_datalen; + break; + + case TLS_extension_pre_shared_key: + { + const uint8_t *psk_identities; + size_t psk_identities_len; + const uint8_t *binders; + size_t binders_len; + const uint8_t *_psk_identities; + size_t _psk_identities_len; + + if (!ext_data) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } + if (tls13_client_pre_shared_key_from_bytes(&psk_identities, &psk_identities_len, + &binders, &binders_len, ext_data, ext_datalen) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } + if (tls13_client_pre_shared_key_from_bytes(&_psk_identities, &_psk_identities_len, + &binders, &binders_len, _ext_data, _ext_datalen) != 1) { + error_print(); + return -1; + } + while (psk_identities_len) { + const uint8_t *id; + size_t idlen; + uint32_t age; + const uint8_t *_id; + size_t _idlen; + int match = 0; + + if (tls13_psk_identity_from_bytes(&id, &idlen, &age, &psk_identities, &psk_identities_len) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } + while (_psk_identities_len) { + if (tls13_psk_identity_from_bytes(&_id, &_idlen, &age, &_psk_identities, &_psk_identities_len) != 1) { + error_print(); + return -1; + } + if (idlen == _idlen && memcmp(id, _id, _idlen) == 0) { + match = 1; + break; + } + } + if (!match) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + } + pre_shared_key = ext_data; + pre_shared_key_len = ext_datalen; + } + break; + + default: + if (ext_datalen != _ext_datalen + || memcmp(ext_data, _ext_data, _ext_datalen) != 0) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + } } - if (!supported_versions || !supported_groups || !key_share || !signature_algorithms) { + + // client must echo ClientHello1.cookie + if (conn->cookie && !cookie) { error_print(); tls13_send_alert(conn, TLS_alert_missing_extension); return -1; } - if (tls13_process_key_share_client_hello_again(key_share, key_share_len, - conn->key_exchange_group, &key_exchange, &key_exchange_len) != 1) { - error_print(); - tls13_send_alert(conn, TLS_alert_decode_error); - return -1; - } - if (key_exchange_len != 65) { - error_print(); - return -1; - } - memcpy(conn->peer_key_exchange, key_exchange, key_exchange_len); - conn->peer_key_exchange_len = key_exchange_len; - - // cookie if (cookie) { const uint8_t *cookie_data; @@ -6671,16 +7123,55 @@ int tls13_recv_client_hello_again(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } - } else { - if (conn->cookie) { - error_print(); - tls13_send_alert(conn, TLS_alert_illegal_parameter); - return -1; + } + + // key_share + if (tls13_process_key_share_client_hello_again(key_share, key_share_len, + conn->key_exchange_group, &key_exchange, &key_exchange_len) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_decode_error); + return -1; + } + if (key_exchange_len != 65) { + error_print(); + return -1; + } + memcpy(conn->peer_key_exchange, key_exchange, key_exchange_len); + conn->peer_key_exchange_len = key_exchange_len; + + // pre_shared_key + if (pre_shared_key) { + if (conn->key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) { + size_t selected_psk_identity = conn->selected_psk_identity; + conn->selected_psk_identity = 0; + + if (conn->psk_identities_len) { + if (tls13_process_client_pre_shared_key_external(conn, + pre_shared_key, pre_shared_key_len) != 1) { + tls13_send_alert(conn, TLS_alert_illegal_parameter); + error_print(); + return -1; + } + } else if (conn->ctx->session_ticket_key) { + if (tls13_process_client_pre_shared_key_from_ticket(conn, + pre_shared_key, pre_shared_key_len) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } + } + if (conn->selected_psk_identity != selected_psk_identity) { + error_print(); + tls13_send_alert(conn, TLS_alert_illegal_parameter); + return -1; + } } } - - digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5); + if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { + error_print(); + return -1; + } if (client_verify) tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5); @@ -6697,7 +7188,7 @@ int tls13_send_server_hello(TLS_CONNECT *conn) if (conn->recordlen == 0) { uint8_t exts[256]; - uint8_t *p = exts; + uint8_t *pexts = exts; size_t extslen = 0; tls_record_set_protocol(conn->record, TLS_protocol_tls12); @@ -6709,41 +7200,48 @@ int tls13_send_server_hello(TLS_CONNECT *conn) return -1; } + // exts in SH + // * supported_versions + // * key_share + // * pre_shared_key + // supported_versions - if (tls13_server_supported_versions_ext_to_bytes(conn->protocol, &p, &extslen) != 1) { + if (tls13_server_supported_versions_ext_to_bytes( + conn->protocol, &pexts, &extslen) != 1) { error_print(); return -1; } - // pre_shared_key - if (conn->pre_shared_key) { - if (tls13_server_pre_shared_key_ext_to_bytes(conn->selected_psk_identity, &p, &extslen) != 1) { - error_print(); - return -1; - } - } - // key_share - if (conn->key_exchange_modes != TLS_KE_PSK) { + if (conn->key_exchange_modes & (TLS_KE_CERT_DHE|TLS_KE_PSK_DHE)) { int curve_oid; if (!conn->key_exchange_group) { error_print(); return -1; } - if ((curve_oid = tls_named_curve_oid(conn->key_exchange_group)) == OID_undef) { error_print(); return -1; } - if (x509_key_generate(&conn->key_exchanges[0], OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) { + if (x509_key_generate(&conn->key_exchanges[0], + OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) { error_print(); return -1; } conn->key_exchange_idx = 0; conn->key_exchanges_cnt = 1; + if (tls13_key_share_server_hello_ext_to_bytes( + &conn->key_exchanges[0], &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } - if (tls13_key_share_server_hello_ext_to_bytes(&conn->key_exchanges[0], &p, &extslen) != 1) { + // pre_shared_key + if (conn->key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) { + if (tls13_server_pre_shared_key_ext_to_bytes( + conn->selected_psk_identity, &pexts, &extslen) != 1) { error_print(); return -1; } @@ -6757,11 +7255,11 @@ int tls13_send_server_hello(TLS_CONNECT *conn) } tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); - if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { error_print(); return -1; } + tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); if (tls13_generate_handshake_keys(conn) != 1) { error_print(); @@ -6828,23 +7326,47 @@ int tls13_send_encrypted_extensions(TLS_CONNECT *conn) if (conn->recordlen == 0) { uint8_t exts[256]; - uint8_t *p = exts; + uint8_t *pexts = exts; size_t extslen = 0; size_t padding_len; tls_record_set_protocol(conn->plain_record, TLS_protocol_tls12); - // supported_groups + // Exts in EE (see RFC 8446 page 37) + // * supported_groups + // * server_name + // * early_data + // * application_layer_protocol_negotiation + // * use_srtp + // * client_certificate_type + // * server_certificate_type + // * max_fragment_length + // * heartbeat + // * record_size_limit (RFC 8449) + // supported_groups if (conn->key_exchange_modes & (TLS_KE_CERT_DHE|TLS_KE_PSK_DHE)) { if (tls_supported_groups_ext_to_bytes(conn->ctx->supported_groups, - conn->ctx->supported_groups_cnt, &p, &extslen) != 1) { + conn->ctx->supported_groups_cnt, &pexts, &extslen) != 1) { error_print(); return -1; } } + + // server_name + if (conn->server_name) { + if (tls_ext_to_bytes(TLS_extension_server_name, NULL, 0, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + + // early_data + // ClientHello.early_data + // PSK_DHE or PSK + // no HelloRetryRequest if (conn->early_data) { - if (tls_ext_to_bytes(TLS_extension_early_data, NULL, 0, &p, &extslen) != 1) { + if (tls_ext_to_bytes(TLS_extension_early_data, NULL, 0, &pexts, &extslen) != 1) { error_print(); return -1; } @@ -6859,6 +7381,10 @@ int tls13_send_encrypted_extensions(TLS_CONNECT *conn) 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_handshake_digest_print(stderr, 0, 0, "EncryptedExtensions", &conn->dgst_ctx); + + tls13_padding_len_rand(&padding_len); format_bytes(stderr, 0, 0, "server_seq_num", conn->server_seq_num, 8); @@ -6887,37 +7413,84 @@ int tls13_send_encrypted_extensions(TLS_CONNECT *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 ca_names[256]; - size_t ca_names_len; + const uint8_t *request_context = NULL; + size_t request_context_len = 0; uint8_t exts[256]; - uint8_t *p = exts; + uint8_t *pexts = exts; size_t extslen = 0; size_t padding_len; - if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names), - conn->ctx->cacerts, conn->ctx->cacertslen) != 1) { + // exts in CR (from RFC 8446 page 37) + // * signature_algorithms + // * signature_algorithms_cert + // * certificate_authorities + // * oid_filters + // * status_request + // * signed_certificate_timestamp + + // signature_algorithms + if (!conn->signature_algorithms_cnt) { error_print(); return -1; } + // subset of ClientHello.signature_algorithms if (tls_signature_algorithms_ext_to_bytes( - conn->signature_algorithms, conn->signature_algorithms_cnt, &p, &extslen) != 1 - || tls13_signature_algorithms_cert_ext_to_bytes( - conn->signature_algorithms, conn->signature_algorithms_cnt, &p, &extslen) != 1 - || tls13_certificate_authorities_ext_to_bytes( - ca_names, ca_names_len, &p, &extslen) != 1) { + conn->signature_algorithms, conn->signature_algorithms_cnt, + &pexts, &extslen) != 1) { error_print(); return -1; } + // signature_algorithms_cert, only when ClientHello.signature_algorithms_cert + if (conn->signature_algorithms_cert) { + if (tls13_signature_algorithms_cert_ext_to_bytes( + conn->signature_algorithms, conn->signature_algorithms_cnt, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + + // certificate_authorities + if (conn->certificate_authorities) { + if (tls13_certificate_authorities_ext_to_bytes( + conn->ctx->ca_names, conn->ctx->ca_names_len, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + + // oid_filters + if (conn->oid_filters) { + if (tls13_oid_filters_ext_to_bytes( + conn->ctx->oid_filters, conn->ctx->oid_filters_len, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + + // status_request + if (conn->status_request) { + if (tls_ext_to_bytes(TLS_extension_status_request, NULL, 0, &pexts, &extslen) != 1) { + error_print(); + return -1; + } + } + + // signed_certificate_timestamp + if (conn->signed_certificate_timestamp) { + if (tls_ext_to_bytes(TLS_extension_signed_certificate_timestamp, NULL, 0, &pexts, &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) { @@ -6957,7 +7530,7 @@ int tls13_send_server_certificate(TLS_CONNECT *conn) { int ret; - tls_trace("send {Certificate}\n"); + tls_trace("send server {Certificate}\n"); if (conn->recordlen == 0) { const uint8_t *request_context = NULL; @@ -6968,15 +7541,19 @@ int tls13_send_server_certificate(TLS_CONNECT *conn) size_t entity_signed_certificate_timestamp_len = 0; size_t padding_len; + // status_request if (conn->status_request) { entity_status_request_ocsp_response = conn->status_request_ocsp_response; entity_status_request_ocsp_response_len = conn->status_request_ocsp_response_len; } + // if ClientHello.status_request, CertificateRequest.status_request = 1 + // signed_certificate_timestamp if (conn->signed_certificate_timestamp) { entity_signed_certificate_timestamp = conn->signed_certificate_timestamp_list; entity_signed_certificate_timestamp_len = conn->signed_certificate_timestamp_list_len; } + // if ClientHello.signed_certificate_timestamp, CertificateRequest.signed_certificate_timestamp = 1 if (tls13_record_set_handshake_certificate(conn->plain_record, &conn->plain_recordlen, request_context, request_context_len, @@ -6993,8 +7570,7 @@ int tls13_send_server_certificate(TLS_CONNECT *conn) error_print(); return -1; } - - format_bytes(stderr, 0, 0, "server_seq_num", conn->server_seq_num, 8); + tls_handshake_digest_print(stderr, 0, 0, "ServerCertificate", &conn->dgst_ctx); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, @@ -7016,33 +7592,20 @@ int tls13_send_server_certificate(TLS_CONNECT *conn) return 1; } + int tls13_send_server_certificate_verify(TLS_CONNECT *conn) { int ret; - tls_trace("send {CertificateVerify}\n"); + tls_trace("send server {CertificateVerify}\n"); if (conn->recordlen == 0) { - X509_KEY *sign_key = &conn->ctx->x509_keys[conn->cert_chain_idx]; - int sig_alg = 0; + X509_KEY *sign_key = &conn->ctx->x509_keys[conn->cert_chain_idx - 1]; uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; size_t siglen; size_t padding_len; - size_t i; - - for (i = 0; i < conn->ctx->signature_algorithms_cnt; i++) { - if (tls_signature_scheme_group_oid(conn->ctx->signature_algorithms[i]) == sign_key->algor_param) { - sig_alg = conn->ctx->signature_algorithms[i]; - break; - } - } - if (!sig_alg) { - error_print(); - return -1; - } - - if (tls13_sign_certificate_verify(TLS_server_mode, sig_alg, + if (tls13_sign_certificate_verify(TLS_server_mode, conn->sig_alg, sign_key, &conn->dgst_ctx, sig, &siglen) != 1) { error_print(); return -1; @@ -7050,21 +7613,18 @@ int tls13_send_server_certificate_verify(TLS_CONNECT *conn) if (tls13_record_set_handshake_certificate_verify( conn->plain_record, &conn->plain_recordlen, - sig_alg, sig, siglen) != 1) { + conn->sig_alg, sig, siglen) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_internal_error); return -1; } tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); - if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { error_print(); return -1; } - format_bytes(stderr, 0, 0, "server_seq_num", conn->server_seq_num, 8); - 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, @@ -7089,7 +7649,7 @@ int tls13_send_server_finished(TLS_CONNECT *conn) int ret; size_t padding_len; - tls_trace("send {Finished}\n"); + tls_trace("send server {Finished}\n"); if (conn->recordlen == 0) { @@ -7112,6 +7672,9 @@ int tls13_send_server_finished(TLS_CONNECT *conn) } tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); + tls_handshake_digest_print(stderr, 0, 0, "ServerFinished", &conn->dgst_ctx); + + format_bytes(stderr, 0, 0, "server_seq_num", conn->server_seq_num, 8); tls13_padding_len_rand(&padding_len); if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv, @@ -7156,20 +7719,22 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn) size_t padding_len; const uint8_t *request_context; size_t request_context_len; - const uint8_t *status_request_ocsp_response; + const uint8_t *status_request_ocsp_response = NULL; size_t status_request_ocsp_response_len; - const uint8_t *signed_certificate_timestamp; + const uint8_t *signed_certificate_timestamp = NULL; size_t signed_certificate_timestamp_len; - /* - uint8_t *p; - const uint8_t *cp; - size_t len = 0; - */ + const int *signature_algorithms_cert = NULL; + size_t signature_algorithms_cert_cnt = 0; + const uint8_t *ca_names = NULL; + size_t ca_names_len = 0; + const uint8_t *oid_filters = NULL; + size_t oid_filters_len = 0; + + int verify_result; tls_trace("recv {Certificate*}\n"); - if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { error_print(); @@ -7192,13 +7757,18 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_bad_record_mac); return -1; } + tls_seq_num_incr(conn->client_seq_num); + tls13_record_trace(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); - + if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { + error_print(); + return -1; + } if ((ret = tls13_record_get_handshake_certificate(conn->plain_record, &request_context, &request_context_len, - conn->client_certs, &conn->client_certs_len, sizeof(conn->client_certs), + conn->peer_cert_chain, &conn->peer_cert_chain_len, sizeof(conn->peer_cert_chain), &status_request_ocsp_response, &status_request_ocsp_response_len, &signed_certificate_timestamp, &signed_certificate_timestamp_len)) < 0) { error_print(); @@ -7214,49 +7784,68 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } - if (!conn->client_certs_len) { + if (!conn->peer_cert_chain_len) { error_print(); tls13_send_alert(conn, TLS_alert_illegal_parameter); return -1; } - // verify cert_chain - int i; - if (tls13_client_cert_chains_select(conn->client_certs, conn->client_certs_len, + // client cert_chain match CertificateRequest extensions + if (conn->signature_algorithms_cert) { + signature_algorithms_cert = conn->ctx->signature_algorithms; + signature_algorithms_cert_cnt = conn->ctx->signature_algorithms_cnt; + } + if (conn->certificate_authorities) { + ca_names = conn->ctx->ca_names; + ca_names_len = conn->ctx->ca_names_len; + } + if (conn->oid_filters) { + oid_filters = conn->ctx->oid_filters; + oid_filters_len = conn->ctx->oid_filters_len; + } + if (tls_cert_chain_match_extensions(conn->peer_cert_chain, conn->peer_cert_chain_len, conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, - conn->ctx->signature_algorithms, conn->ctx->signature_algorithms_cnt, - conn->ctx->cacerts, conn->ctx->cacertslen, - NULL, NULL, NULL, NULL) != 1) { + signature_algorithms_cert, signature_algorithms_cert_cnt, + ca_names, ca_names_len, + oid_filters, oid_filters_len, + NULL, 0, // server_name not in CertificateRequest + NULL) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_bad_certificate); return -1; } - int verify_result; - if (x509_certs_verify(conn->client_certs, conn->client_certs_len, X509_cert_chain_client, + + // verify client cert_chain + if (x509_certs_verify(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_client, conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) { error_print(); tls13_send_alert(conn, TLS_alert_bad_certificate); return -1; } - - if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) { - error_print(); - return -1; + // status_request + if (status_request_ocsp_response) { + if (ocsp_response_verify( + status_request_ocsp_response, status_request_ocsp_response_len, + conn->ctx->cacerts, conn->ctx->cacertslen) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_certificate_revoked); + return -1; + } + } + // signed_certificate_timestamp + if (signed_certificate_timestamp) { + if (tls13_signed_certificate_timestamp_verify( + signed_certificate_timestamp, signed_certificate_timestamp_len) != 1) { + error_print(); + tls13_send_alert(conn, TLS_alert_bad_certificate); + return -1; + } } - - tls_seq_num_incr(conn->client_seq_num); return 1; } -/* -struct { - SignatureScheme algorithm; - opaque signature<0..2^16-1>; -} CertificateVerify; -*/ - int tls13_recv_client_finished(TLS_CONNECT *conn) { int ret; @@ -7269,7 +7858,7 @@ int tls13_recv_client_finished(TLS_CONNECT *conn) uint8_t client_write_key[16]; - tls_trace("recv {Finished}\n"); + tls_trace("recv client {Finished}\n"); if ((ret = tls_recv_record(conn)) != 1) { if (ret != TLS_ERROR_RECV_AGAIN) { error_print(); @@ -7291,6 +7880,8 @@ int tls13_recv_client_finished(TLS_CONNECT *conn) tls13_send_alert(conn, TLS_alert_bad_record_mac); return -1; } + tls_seq_num_incr(conn->client_seq_num); + tls13_record_trace(stderr, conn->plain_record, conn->plain_recordlen, 0, 0); @@ -7305,11 +7896,15 @@ int tls13_recv_client_finished(TLS_CONNECT *conn) return -1; } + tls_handshake_digest_print(stderr, 0, 0, "before ClientFinished", &conn->dgst_ctx); + if (tls13_compute_verify_data(conn->client_handshake_traffic_secret, &conn->dgst_ctx, local_verify_data, &local_verify_data_len) != 1) { error_print(); return -1; } + memset(&conn->dgst_ctx, 0, sizeof(conn->dgst_ctx)); + if (local_verify_data_len != verify_data_len || memcmp(local_verify_data, verify_data, verify_data_len) != 0) { error_print(); @@ -7317,13 +7912,6 @@ int tls13_recv_client_finished(TLS_CONNECT *conn) return -1; } - // 这个应该放在哪个位置? - if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) { - error_print(); - return -1; - } - tls_seq_num_incr(conn->client_seq_num); - // update client_write_key, client_write_iv, reset client_seq_num tls13_hkdf_expand_label(conn->digest, conn->client_application_traffic_secret, "key", NULL, 0, 16, client_write_key); @@ -7339,14 +7927,6 @@ int tls13_recv_client_finished(TLS_CONNECT *conn) return 1; } - - - - - - -// 这个函数是否有必要存在?应该是隐含的 -// 这个函数只在一个地方被调用,应该在那里展开 int tls13_send_early_data(TLS_CONNECT *conn) { size_t sentlen; @@ -7361,10 +7941,18 @@ int tls13_send_early_data(TLS_CONNECT *conn) error_print(); return -1; } - if (tls13_send(conn, conn->early_data_buf, conn->early_data_len, &sentlen) != 1) { - error_print(); - return -1; + + while (conn->early_data_offset < conn->early_data_len) { + int ret; + if ((ret = tls13_send(conn, conn->early_data_buf + conn->early_data_offset, + conn->early_data_len - conn->early_data_offset, &sentlen)) <= 0) { + if (ret == TLS_ERROR_SEND_AGAIN) { + return ret; + } + } + conn->early_data_offset += sentlen; } + return 1; } @@ -7406,15 +7994,12 @@ int tls13_update_server_application_keys(TLS_CONNECT *conn) return 1; } -// 这个函数应该先构造一个应用层的消息, -int tls13_send_key_update(TLS_CONNECT *conn, int request_update) +// 参数request_update应该根据当前状态设置 +int tls13_send_client_key_update(TLS_CONNECT *conn, int request_update) { int ret; if (conn->recordlen == 0) { - const BLOCK_CIPHER_KEY *key; - const uint8_t *iv; - uint8_t *seq_num; size_t padding_len = 0; tls_trace("send {KeyUpdate}\n"); @@ -7426,30 +8011,51 @@ int tls13_send_key_update(TLS_CONNECT *conn, int request_update) } tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen); - - if (conn->is_client) { - key = &conn->client_write_key; - iv = conn->client_write_iv; - seq_num = conn->client_seq_num; - } else { - key = &conn->server_write_key; - iv = conn->server_write_iv; - seq_num = conn->server_seq_num; - } - tls13_padding_len_rand(&padding_len); - if (tls13_record_encrypt(key, iv, seq_num, - conn->plain_record, conn->plain_recordlen, 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 (conn->is_client) { - tls13_update_client_application_keys(conn); - } else { - tls13_update_server_application_keys(conn); + tls13_update_client_application_keys(conn); + } + + if ((ret = tls_send_record(conn)) != 1) { + if (ret != TLS_ERROR_SEND_AGAIN) { + error_print(); } + return ret; + } + return 1; +} + +int tls13_send_server_key_update(TLS_CONNECT *conn, int request_update) +{ + int ret; + + if (conn->recordlen == 0) { + size_t padding_len = 0; + + tls_trace("send {KeyUpdate}\n"); + + if (tls13_record_set_handshake_key_update(conn->plain_record, &conn->plain_recordlen, + request_update) != 1) { + error_print(); + 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(); + return -1; + } + + tls13_update_server_application_keys(conn); } if ((ret = tls_send_record(conn)) != 1) { @@ -7461,6 +8067,49 @@ int tls13_send_key_update(TLS_CONNECT *conn, int request_update) return 1; } + +/* +Post-Handshake-Auth + + 客户端在 ClientHello 中发送post_handshake_auht说明支持PHA + + 在握手完成并进行数据通信时,如果客户端请求一个特殊的地址 比如 GET /admin + 默认未认证的客户端不能访问此地址,因此服务器端如果发现客户端支持PHA,那么就会给客户端发送一个CertificateRequest + + 客户端不需要立即响应,但是如果客户端响应 + 则需要发出连续的 Certificate, CertificateVerify, Finished消息 + + + +这意味着如果客户端开始发送Certificate + 服务器就必须再次进入到握手的状态机中 + 这意味着SSL再次进入到状态机中 + + +是否意味着每次不论上层调用是read/write,SSL都是按照状态机来处理 + + +*/ + + + + + + + + + + + + + + + + + + + + int tls13_do_client_handshake(TLS_CONNECT *conn) { @@ -7468,41 +8117,29 @@ int tls13_do_client_handshake(TLS_CONNECT *conn) int next_state; + // 客户端的状态机可能还是有问题的 + switch (conn->state) { case TLS_state_hello_retry_request: case TLS_state_client_hello_again: case TLS_state_server_hello: case TLS_state_encrypted_extensions: - if (conn->early_data && conn->early_data_len) { + if (conn->early_data && conn->early_data_offset < conn->early_data_len) { tls_trace("send EarlyData\n"); if (tls13_send_early_data(conn) != 1) { error_print(); return -1; } - conn->early_data_len = 0; } break; } - switch (conn->state) { case TLS_state_client_hello: ret = tls13_send_client_hello(conn); - /* - if (conn->early_data) - next_state = TLS_state_early_data; - else next_state = TLS_state_hello_retry_request; - */ next_state = TLS_state_hello_retry_request; break; - /* - case TLS_state_early_data: - ret = tls13_send_early_data(conn); - next_state = TLS_state_hello_retry_request; - break; - */ - case TLS_state_hello_retry_request: // optional ret = tls13_recv_hello_retry_request(conn); if (conn->hello_retry_request) @@ -7529,7 +8166,7 @@ int tls13_do_client_handshake(TLS_CONNECT *conn) ret = tls13_recv_certificate_request(conn); if (conn->key_exchange_modes == TLS_KE_CERT_DHE) next_state = TLS_state_server_certificate; - else next_state = TLS_state_server_finished; // recv_server_finished 有可能存在报文已经被解密的情况 + else next_state = TLS_state_server_finished; break; case TLS_state_server_certificate: @@ -7538,7 +8175,7 @@ int tls13_do_client_handshake(TLS_CONNECT *conn) break; case TLS_state_certificate_verify: - ret = tls13_recv_certificate_verify(conn); + ret = tls13_recv_server_certificate_verify(conn); next_state = TLS_state_server_finished; break; @@ -7557,8 +8194,13 @@ int tls13_do_client_handshake(TLS_CONNECT *conn) break; case TLS_state_client_certificate: + // if client has no (proper) certificate + // client will send {Certificate} with empty certificate_list + // but will not send {CertificateVerify} ret = tls13_send_client_certificate(conn); - next_state = TLS_state_client_certificate_verify; + if (conn->cert_chain) + next_state = TLS_state_client_certificate_verify; + else next_state = TLS_state_client_finished; break; case TLS_state_client_certificate_verify: @@ -7569,16 +8211,8 @@ int tls13_do_client_handshake(TLS_CONNECT *conn) case TLS_state_client_finished: ret = tls13_send_client_finished(conn); next_state = TLS_state_handshake_over; - //next_state = TLS_state_new_session_ticket; break; - /* - case TLS_state_new_session_ticket: - ret = tls13_recv_new_session_ticket(conn); - next_state = TLS_state_handshake_over; - break; - */ - default: error_print(); return -1; @@ -7659,7 +8293,6 @@ int tls13_do_server_handshake(TLS_CONNECT *conn) 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; @@ -7685,7 +8318,7 @@ int tls13_do_server_handshake(TLS_CONNECT *conn) break; case TLS_state_client_certificate_verify: - ret = tls13_recv_certificate_verify(conn); + ret = tls13_recv_client_certificate_verify(conn); next_state = TLS_state_client_finished; break; @@ -7781,12 +8414,6 @@ int tls13_do_connect(TLS_CONNECT *conn) conn->state = TLS_state_client_hello; sm3_init(&conn->sm3_ctx); - - if (tls13_handshake_prepare(conn) != 1) { - error_print(); - return -1; - } - while (1) { ret = tls13_client_handshake(conn); @@ -7829,11 +8456,6 @@ int tls13_do_accept(TLS_CONNECT *conn) fprintf(stderr, "tls13_do_accept\n"); - if (tls13_handshake_prepare(conn) != 1) { - error_print(); - return -1; - } - while (1) { ret = tls13_server_handshake(conn); @@ -7881,3 +8503,13 @@ int tls13_ctx_set_max_key_exchanges(TLS_CTX *ctx, size_t cnt) return 1; } +int tls13_enable_post_handshake_auth(TLS_CONNECT *conn) +{ + if (!conn) { + error_print(); + return -1; + } + conn->post_handshake_auth = 1; + return 1; +} + diff --git a/src/tls_ext.c b/src/tls_ext.c index 8157cf86..3ffd0714 100644 --- a/src/tls_ext.c +++ b/src/tls_ext.c @@ -327,7 +327,7 @@ Example: */ -int tls_signature_algorithms_print_ex(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen) +int tls_signature_algorithms_print(FILE *fp, int fmt, int ind, const uint8_t *d, size_t dlen) { const uint8_t *sig_algs; size_t sig_algs_len; @@ -355,6 +355,23 @@ int tls_signature_algorithms_print_ex(FILE *fp, int fmt, int ind, const char *la return 1; } + +int tls_enable_signature_algorithms_cert(TLS_CONNECT *conn) +{ + if (!conn) { + error_print(); + return -1; + } + if (!conn->ctx->signature_algorithms_cnt) { + error_print(); + return -1; + } + conn->signature_algorithms_cert = 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) { @@ -372,7 +389,7 @@ int tls13_signature_algorithms_cert_print(FILE *fp, int fmt, int ind, const uint } return 1; } - +*/ diff --git a/src/tls_ocsp.c b/src/tls_ocsp.c index 74dcce78..b3da111e 100644 --- a/src/tls_ocsp.c +++ b/src/tls_ocsp.c @@ -28,7 +28,6 @@ #include - /* status_request(5) @@ -46,7 +45,6 @@ ClientHello.status_request } OCSPStatusRequest; */ -// 如果两个参数都为空的话,我们应该提供一个空的request int tls_ocsp_status_request_to_bytes( const uint8_t *responder_id_list, size_t responder_id_list_len, // optional const uint8_t *request_exts, size_t request_exts_len, // optinoal @@ -302,11 +300,11 @@ int tls13_set_client_status_request(TLS_CONNECT *conn, error_print(); return -1; } - conn->status_request = 1; conn->status_request_responder_id_list = status_request_responder_id_list; conn->status_request_responder_id_list_len = status_request_responder_id_list_len; conn->status_request_exts = status_request_exts; conn->status_request_exts_len = status_request_exts_len; + conn->status_request = 1; return 1; } diff --git a/src/tls_psk.c b/src/tls_psk.c index cee2e441..c2ba6d08 100644 --- a/src/tls_psk.c +++ b/src/tls_psk.c @@ -735,6 +735,7 @@ int tls13_send_new_session_ticket(TLS_CONNECT *conn) return 1; } +// 这个函数是有点问题的,还是应该改为recv_new_session_ticket int tls13_process_new_session_ticket(TLS_CONNECT *conn) { int ret; @@ -756,7 +757,6 @@ int tls13_process_new_session_ticket(TLS_CONNECT *conn) const uint8_t *cp; size_t len; - // only cheching encoding if ((ret = tls13_record_get_handshake_new_session_ticket(conn->plain_record, &ticket_lifetime, &ticket_age_add, &ticket_nonce, &ticket_nonce_len, @@ -775,6 +775,9 @@ int tls13_process_new_session_ticket(TLS_CONNECT *conn) const uint8_t *ext_data; size_t ext_datalen; + // exts in NST + // * early_data + if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &exts, &extslen) != 1) { error_print(); return -1; diff --git a/src/tls_sct.c b/src/tls_sct.c index 85d451fc..a8b7b0ee 100644 --- a/src/tls_sct.c +++ b/src/tls_sct.c @@ -163,3 +163,13 @@ int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx) ctx->signed_certificate_timestamp = 1; return 1; } + + +int tls13_signed_certificate_timestamp_verify(const uint8_t *sct_list, size_t sct_list_len) +{ + //error_print(); + return 1; +} + + + diff --git a/src/tls_sni.c b/src/tls_sni.c index d02b52a0..1da11e55 100644 --- a/src/tls_sni.c +++ b/src/tls_sni.c @@ -130,7 +130,7 @@ int tls_server_name_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, s return -1; } format_print(fp, fmt, ind, "name_type: %s (%d)\n", name_type == 0 ? "host_name" : "(unknown)", name_type); - format_bytes(fp, fmt, ind, "host_name", host_name, host_name_len); // TODO: print string + format_string(fp, fmt, ind, "host_name", host_name, host_name_len); // TODO: print string } if (ext_datalen) { error_print(); diff --git a/tests/tls13test.c b/tests/tls13test.c index 90095b1b..ab7aed2c 100644 --- a/tests/tls13test.c +++ b/tests/tls13test.c @@ -448,7 +448,7 @@ static int test_tls13_signature_algorithms_cert_ext(void) error_print(); return -1; } - tls13_signature_algorithms_cert_print(stderr, 0, 4, ext_data, ext_datalen); + 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, diff --git a/tools/tls13_client.c b/tools/tls13_client.c index 5aeb7ce7..32f8945c 100644 --- a/tools/tls13_client.c +++ b/tools/tls13_client.c @@ -37,6 +37,10 @@ static const char *help = " -cert file Client's certificate chain in PEM format\n" " -key file Client's encrypted private key in PEM format\n" " -pass str Password to decrypt private key\n" +" -server_name Send server_name (SNI) request\n" +" -signature_algorithms_cert Send signature_algorithms_cert extension\n" +" -status_request Send status_request (OCSP Stapling) request\n" +" -ct Send signed_certificate_timestamp (SCT) request\n" " -psk_ke Support PSK-only key exchange\n" " -psk_dhe_ke Support PSK with (EC)DHE key exchange\n" " -psk_identity str PSK Identity\n" @@ -45,6 +49,7 @@ static const char *help = " -sess_in Load server's session ticket file\n" " -sess_out Save server's session ticket file\n" " -early_data file Send early data, -psk_ke and/or -psk_dhe_ke should be set\n" +" -post_handshake_auth Support post_handshake_auth\n" "\n" "CipherSuites\n" " TLS_SM4_GCM_SM3 TLS 1.3\n" @@ -138,7 +143,11 @@ int tls13_client_main(int argc, char *argv[]) size_t sig_algs_cnt = 0; - + int server_name = 0; + int signature_algorithms_cert = 0; + int status_request = 0; + int signed_certificate_timestamp = 0; + int post_handshake_auth = 0; argc--; argv++; @@ -169,6 +178,16 @@ int tls13_client_main(int argc, char *argv[]) } else if (!strcmp(*argv, "-pass")) { if (--argc < 1) goto bad; pass = *(++argv); + } else if (!strcmp(*argv, "-server_name")) { + server_name = 1; + } else if (!strcmp(*argv, "-signature_algorithms_cert")) { + signature_algorithms_cert = 1; + } else if (!strcmp(*argv, "-status_request")) { + status_request = 1; + } else if (!strcmp(*argv, "-ct")) { + signed_certificate_timestamp = 1; + } else if (!strcmp(*argv, "-post_handshake_auth")) { + post_handshake_auth = 1; } else if (!strcmp(*argv, "-sess_in")) { if (--argc < 1) goto bad; sess_in = *(++argv); @@ -286,29 +305,22 @@ bad: memset(&ctx, 0, sizeof(ctx)); memset(&conn, 0, sizeof(conn)); - server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); - server.sin_family = AF_INET; - server.sin_port = htons(port); - if (tls_socket_create(&sock, AF_INET, SOCK_STREAM, 0) != 1) { - fprintf(stderr, "%s: socket create error\n", prog); - goto end; - } - if (tls_socket_connect(sock, &server) != 1) { - fprintf(stderr, "%s: socket connect error\n", prog); - goto end; - } + + if (tls_ctx_init(&ctx, TLS_protocol_tls13, TLS_client_mode) != 1) { fprintf(stderr, "%s: context init error\n", prog); goto end; } + /* if (!cipher_suites_cnt) { error_print(); fprintf(stderr, "%s: option '-cipher_suite' required\n", prog); goto end; } + */ if (tls_ctx_set_cipher_suites(&ctx, cipher_suites, cipher_suites_cnt) != 1) { fprintf(stderr, "%s: context init error\n", prog); @@ -364,11 +376,39 @@ bad: - if (tls_init(&conn, &ctx) != 1) { + if (tls13_init(&conn, &ctx) != 1) { fprintf(stderr, "%s: error\n", prog); goto end; } + + if (server_name) { + if (tls_set_server_name(&conn, (uint8_t *)host, strlen(host)) != 1) { + error_print(); + goto end; + } + } + + if (signature_algorithms_cert) { + if (tls_enable_signature_algorithms_cert(&conn) != 1) { + error_print(); + return -1; + } + } + + if (status_request) { + if (tls13_set_client_status_request(&conn, NULL, 0, NULL, 0) != 1) { + error_print(); + goto end; + } + } + if (signed_certificate_timestamp) { + if (tls_enable_signed_certificate_timestamp(&conn) != 1) { + error_print(); + goto end; + } + } + if (sess_in) { FILE *sess_infp; int enable_psk = 0; @@ -470,6 +510,23 @@ bad: fclose(early_data_fp); } + if (post_handshake_auth) { + } + + + + server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]); + server.sin_family = AF_INET; + server.sin_port = htons(port); + + if (tls_socket_create(&sock, AF_INET, SOCK_STREAM, 0) != 1) { + fprintf(stderr, "%s: socket create error\n", prog); + goto end; + } + if (tls_socket_connect(sock, &server) != 1) { + fprintf(stderr, "%s: socket connect error\n", prog); + goto end; + } if (tls_set_socket(&conn, sock) != 1 diff --git a/tools/tls13_server.c b/tools/tls13_server.c index da0222b3..953609af 100644 --- a/tools/tls13_server.c +++ b/tools/tls13_server.c @@ -77,13 +77,23 @@ static const char *help = " cat signcert.pem > certs.pem\n" " cat cacert.pem >> certs.pem\n" "\n" -" sudo gmssl tls13_server -port 4430 -cert certs.pem -key signkey.pem -pass 1234\n" -" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacert.pem\n" +" sudo gmssl tls13_server -port 4430 -cert certs.pem -key signkey.pem -pass 1234 -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacert.pem -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" "\n" -" sudo gmssl tls13_server -port 4430 -cert certs.pem -key signkey.pem -pass 1234 \n" -" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \n" -" -supported_group sm2p256v1 -supported_group prime256v1\n" +" sudo gmssl tls13_server -port 4430 -cert certs.pem -key signkey.pem -pass 1234 \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n" +" -supported_group sm2p256v1 -supported_group prime256v1 \\\n" " -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256\n" +" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacert.pem \\\n" +" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n" +" -supported_group sm2p256v1 -supported_group prime256v1 \\\n" +" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n" +" -max_key_exchanges 2 \\\n" +" -server_name \\\n" +" -signature_algorithms_cert \\\n" +" -status_request \\\n" +" -post_handshake_auth \\\n" +" -ct\n" "\n" " PSK=1122334455667788112233445566778811223344556677881122334455667788\n" " sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" @@ -276,10 +286,12 @@ bad: argv++; } + /* if (!cipher_suites_cnt) { error_print(); goto end; } + */ if (tls_socket_lib_init() != 1) { error_print(); @@ -398,11 +410,18 @@ bad: fprintf(stderr, "%s: socket bind error\n", prog); goto end; } + + if (tls13_init(&conn, &ctx) != 1) { + error_print(); + return -1; + } + puts("start listen ...\n"); tls_socket_listen(sock, 1); + restart: //client_addrlen = sizeof(client_addr); @@ -412,8 +431,7 @@ restart: } puts("socket connected\n"); - if (tls_init(&conn, &ctx) != 1 - || tls_set_socket(&conn, conn_sock) != 1) { + if (tls_set_socket(&conn, conn_sock) != 1) { error_print(); return -1; }