Update TLS 1.3

All tls13_server examples passed.
This commit is contained in:
Zhi Guan
2026-05-09 13:17:36 +08:00
parent 4c54385534
commit 2c72cf84b3
9 changed files with 334 additions and 67 deletions

View File

@@ -513,6 +513,7 @@ endif()
if (ENABLE_AES) if (ENABLE_AES)
message(STATUS "ENABLE_AES is ON") message(STATUS "ENABLE_AES is ON")
add_definitions(-DENABLE_AES)
list(APPEND src src/aes.c src/aes_modes.c) list(APPEND src src/aes.c src/aes_modes.c)
list(APPEND tests aes) list(APPEND tests aes)
endif() endif()

View File

@@ -956,7 +956,7 @@ typedef struct {
uint8_t *data; // 让data指向plain_record uint8_t *data; // 让data指向plain_record
size_t datalen; size_t datalen;
size_t sentlen; // 用于tls13_send
int protocol; int protocol;
@@ -1649,12 +1649,6 @@ int tls_cert_chain_match_signature_algorithms_cert(
const uint8_t *cert_chain, size_t cert_chain_len, const uint8_t *cert_chain, size_t cert_chain_len,
const int *signature_algorithms_cert, size_t signature_algorithms_cert_cnt); 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_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( int tls_cert_chain_match_extensions(
@@ -1959,7 +1953,7 @@ int tls13_key_share_server_hello_print(FILE *fp, int fmt, int ind,
int tls13_ctx_set_max_key_exchanges(TLS_CTX *ctx, size_t cnt); int tls13_ctx_set_max_key_exchanges(TLS_CTX *ctx, size_t cnt);
#define TLS_DEFAULT_KEY_EXCHANGES_CNT 1
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -2243,7 +2243,7 @@ int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client)
// 默认就发送一个,因为只要发送key_share,那么至少有一个group // 默认就发送一个,因为只要发送key_share,那么至少有一个group
ctx->key_exchanges_cnt = 1; ctx->key_exchanges_cnt = TLS_DEFAULT_KEY_EXCHANGES_CNT;
return 1; return 1;

View File

@@ -107,6 +107,8 @@ int tls_recv_record(TLS_CONNECT *conn)
return 1; return 1;
} }
fprintf(stderr, "110 conn->record_offset = %zu\n", conn->record_offset);
if (conn->record_offset < 5) { if (conn->record_offset < 5) {
left = 5 - conn->record_offset; left = 5 - conn->record_offset;
while (left) { while (left) {
@@ -130,6 +132,7 @@ int tls_recv_record(TLS_CONNECT *conn)
left -= n; left -= n;
} }
} }
fprintf(stderr, "135 conn->record_offset = %zu\n", conn->record_offset);
if (conn->record_offset == 5) { if (conn->record_offset == 5) {
if (!tls_record_type_name(tls_record_type(conn->record))) { if (!tls_record_type_name(tls_record_type(conn->record))) {
@@ -146,6 +149,9 @@ int tls_recv_record(TLS_CONNECT *conn)
} }
} }
fprintf(stderr, "152 conn->record_offset = %zu\n", conn->record_offset);
fprintf(stderr, "153 conn->recordlen = %zu\n", tls_record_length(conn->record));
if (conn->record_offset >= tls_record_length(conn->record)) { if (conn->record_offset >= tls_record_length(conn->record)) {
error_print(); error_print();
return -1; return -1;

View File

@@ -29,13 +29,10 @@
static const int tls13_ciphers[] = { TLS_cipher_sm4_gcm_sm3 }; // 在接收到对方的报文的时候,没有检查对方的报文是否为Alert
static size_t tls13_ciphers_count = sizeof(tls13_ciphers)/sizeof(int);
static int tls13_client_hello_exts[] = {
TLS_extension_supported_versions,
TLS_extension_padding,
};
int tls13_random_generate(uint8_t random[32]) int tls13_random_generate(uint8_t random[32])
{ {
@@ -301,9 +298,6 @@ KeyUpate的流程
这里一个主要的状态判断是, 这里一个主要的状态判断是,
某一方在接收到对方的KeyUpdate请求后,是否响。 某一方在接收到对方的KeyUpdate请求后,是否响。
*/ */
@@ -312,11 +306,10 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
int key_update = 0; int key_update = 0;
tls_trace("send {ApplicationData}\n"); tls_trace("send {ApplicationData}\n");
format_print(stderr, 0, 0, "data = %p, datalen = %zu\n", data, datalen);
*sentlen = 0; *sentlen = 0;
// 这个可能是有问题的 // 当前的发送缓冲区是空的,没有之前剩余的数据
if (!conn->recordlen) { if (!conn->recordlen) {
const BLOCK_CIPHER_KEY *key; const BLOCK_CIPHER_KEY *key;
const uint8_t *iv; const uint8_t *iv;
@@ -336,17 +329,17 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
key = &conn->client_write_key; key = &conn->client_write_key;
iv = conn->client_write_iv; iv = conn->client_write_iv;
seq_num = conn->client_seq_num; seq_num = conn->client_seq_num;
format_bytes(stderr, 0, 4, "client_write_iv", iv, 12); //format_bytes(stderr, 0, 4, "client_write_iv", iv, 12);
format_bytes(stderr, 0, 4, "client_seq_num", seq_num, 8); //format_bytes(stderr, 0, 4, "client_seq_num", seq_num, 8);
format_print(stderr, 0, 0, "\n"); //format_print(stderr, 0, 0, "\n");
} else { } else {
key = &conn->server_write_key; key = &conn->server_write_key;
iv = conn->server_write_iv; iv = conn->server_write_iv;
seq_num = conn->server_seq_num; seq_num = conn->server_seq_num;
format_bytes(stderr, 0, 4, "server_write_iv", iv, 12); //format_bytes(stderr, 0, 4, "server_write_iv", iv, 12);
format_bytes(stderr, 0, 4, "server_seq_num", seq_num, 8); //format_bytes(stderr, 0, 4, "server_seq_num", seq_num, 8);
format_print(stderr, 0, 0, "\n"); //format_print(stderr, 0, 0, "\n");
} }
tls13_padding_len_rand(&padding_len); tls13_padding_len_rand(&padding_len);
@@ -366,7 +359,10 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
conn->recordlen = 5 + record_datalen; conn->recordlen = 5 + record_datalen;
conn->record_offset = 0; conn->record_offset = 0;
conn->plain_recordlen = datalen + 5;
// 需要记录密文对应的明文是什么,当完整的报文发送之后,这些信息要返回给调用方
//conn->plain_recordlen = datalen + 5;
conn->sentlen = datalen;
tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen); tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen);
@@ -436,7 +432,8 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
} }
*/ */
*sentlen = conn->plain_recordlen - 5; //*sentlen = conn->plain_recordlen - 5;
*sentlen = conn->sentlen;
return 1; return 1;
} }
@@ -450,8 +447,12 @@ int tls13_do_recv(TLS_CONNECT *conn)
tls_trace("recv {ApplicationData}\n"); tls_trace("recv {ApplicationData}\n");
// 在接收EarlyData的时候,当前的状态有问题啊
switch (conn->state) { switch (conn->state) {
case 0: case 0:
case TLS_state_early_data:
error_print(); error_print();
fprintf(stderr, "----------------------------------------------------------------\n"); fprintf(stderr, "----------------------------------------------------------------\n");
conn->record_offset = 0; conn->record_offset = 0;
@@ -508,6 +509,7 @@ int tls13_do_recv(TLS_CONNECT *conn)
break; break;
default: default:
fprintf(stderr, "conn->state = %d\n", conn->state);
error_print(); error_print();
return -1; return -1;
} }
@@ -700,6 +702,15 @@ int tls13_recv_early_data(TLS_CONNECT *conn)
format_string(stderr, 0, 4, "EarlyData", conn->early_data_buf, conn->early_data_len); format_string(stderr, 0, 4, "EarlyData", conn->early_data_buf, conn->early_data_len);
// 清空记录,防止后续的握手处理过程出现问题
// 需要考虑统一的record状态更新
// 还需要考虑 tls13_recv 如何消费掉 early_data
conn->record_offset = 0;
conn->recordlen = 0;
conn->plain_recordlen = 0;
return 1; return 1;
} }
@@ -3615,6 +3626,23 @@ ClientHello中的很多扩展是和证书有关的
那么就不应该在ClientHello中包含这些扩展 那么就不应该在ClientHello中包含这些扩展
*/ */
/*
1. 客户端发送 ClientHello,包含 early_data 扩展
2. 客户端设置 cipher_suite 和 early_secret
3. 客户端发送 {EarlyData}
4. 客户端发送 {EndOfEarlyData}
5. 客户端接收 ServerHello
6. 客户端设置 handshake_secret
7. 客户端接收 {EncryptedExtensions}
*/
int tls13_send_client_hello(TLS_CONNECT *conn) int tls13_send_client_hello(TLS_CONNECT *conn)
{ {
int ret; int ret;
@@ -3731,6 +3759,8 @@ int tls13_send_client_hello(TLS_CONNECT *conn)
} }
// server_name // server_name
fprintf(stderr, "conn->server_name = %d\n", conn->server_name);
format_string(stderr, 0, 0, "conn->host_name", conn->host_name, conn->host_name_len);
if (conn->server_name) { if (conn->server_name) {
if (tls_server_name_ext_to_bytes( if (tls_server_name_ext_to_bytes(
conn->host_name, conn->host_name_len, &pexts, &extslen) != 1) { conn->host_name, conn->host_name_len, &pexts, &extslen) != 1) {
@@ -3771,6 +3801,8 @@ int tls13_send_client_hello(TLS_CONNECT *conn)
} }
// early_data // early_data
// 客户端启用early_data是非常特殊的,需要在ClientHello就确定cipher_suite
// 并且固定采用第一个pre_shared_key
if (conn->early_data) { if (conn->early_data) {
if (tls_ext_to_bytes(TLS_extension_early_data, NULL, 0, if (tls_ext_to_bytes(TLS_extension_early_data, NULL, 0,
&pexts, &extslen) != 1) { &pexts, &extslen) != 1) {
@@ -3867,9 +3899,18 @@ int tls13_send_client_hello(TLS_CONNECT *conn)
error_print(); error_print();
return -1; return -1;
} }
} }
// backup client_hello // backup client_hello
// 如果后面发送EarlyData,这个数据有可能被修改
// 并且如果确定了发送EarlyData,cipher_suite就确定了,不应该再备份了
// 由于服务器可能拒绝EarlyData,并且不选择第一个PSK
// 那么可能导致最终的cipher_suite和客户端计算EarlyData不同的值
// 这就导致客户端必须重新计算ClientHello的digest
// 因此我们还是保存ClientHello,而不是立即就计算digest
memcpy(conn->plain_record, conn->record, conn->recordlen); memcpy(conn->plain_record, conn->record, conn->recordlen);
conn->plain_recordlen = conn->recordlen; conn->plain_recordlen = conn->recordlen;
} }
@@ -3943,6 +3984,9 @@ int tls13_recv_hello_retry_request(TLS_CONNECT *conn)
if ((ret = tls_recv_record(conn)) != 1) { if ((ret = tls_recv_record(conn)) != 1) {
if (ret != TLS_ERROR_RECV_AGAIN) { if (ret != TLS_ERROR_RECV_AGAIN) {
fprintf(stderr, "tls_recv_record return %d\n", ret);
error_print(); error_print();
} }
return ret; return ret;
@@ -4848,14 +4892,25 @@ int tls13_recv_server_hello(TLS_CONNECT *conn)
} }
tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
} else { } else {
if (digest_init(&conn->dgst_ctx, conn->digest) != 1 if (digest_init(&conn->dgst_ctx, conn->digest) != 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(); error_print();
return -1; return -1;
} }
// update(ClientHello)
if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) {
error_print();
return -1;
}
format_bytes(stderr, 0, 0, "ClientHello data", conn->plain_record + 5, conn->plain_recordlen - 5);
tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx);
// update(ServerHello)
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
error_print();
return -1;
}
format_bytes(stderr, 0, 0, "ServerHello data", conn->record + 5, conn->recordlen - 5);
tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
} }
@@ -5142,7 +5197,11 @@ int tls_cert_match_server_name(const uint8_t *cert, size_t certlen, const uint8_
error_print(); error_print();
return -1; return -1;
} else if (ret == 0) { } else if (ret == 0) {
return TLS_CERT_VERIFY_NO_SUBJECT_ALT_NAME; // certificate without SubjectAltName extension will fail the check
// this is the default policy of major browsers and it is simple
// else we need to check all the cert chains to make sure none of them match the SNI
// then we can choose the default cert chain
return 0;
} }
if (subject_dns_name_len != host_name_len if (subject_dns_name_len != host_name_len
|| memcmp(subject_dns_name, host_name, host_name_len) != 0) { || memcmp(subject_dns_name, host_name, host_name_len) != 0) {
@@ -5190,8 +5249,13 @@ int tls_cert_chain_match_extensions(
return 0; return 0;
} }
// server_name // server_name
if (host_name && host_name_len) { if (host_name && host_name_len) {
format_string(stderr, 0,0, "host_name", host_name, host_name_len);
if ((ret = tls_cert_match_server_name(cert, certlen, if ((ret = tls_cert_match_server_name(cert, certlen,
host_name, host_name_len)) < 0) { host_name, host_name_len)) < 0) {
error_print(); error_print();
@@ -5199,6 +5263,9 @@ int tls_cert_chain_match_extensions(
} else if (ret == 0) { } else if (ret == 0) {
return 0; return 0;
} }
format_print(stderr, 0, 0, "passed\n");
} }
// signature_algorithms_cert // signature_algorithms_cert
@@ -5670,6 +5737,10 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn)
} }
// verify server cert_chain // verify server cert_chain
// 函数x509_certs_verify的设计有问题
// 验证一个证书链之前,应该首先判断一下这个证书链对应的根证书是否存在
// 如果我们没有根证书,那么就根本不能验证
// 把查找根证书和验证证书链的函数分开
if (x509_certs_verify( if (x509_certs_verify(
conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server, conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->cacerts, conn->ctx->cacertslen,
@@ -5942,6 +6013,8 @@ int tls13_recv_server_finished(TLS_CONNECT *conn)
return 1; return 1;
} }
// 需要验证,当cipher_suite为AES,服务器证书为P-256,客户端证书为SM2的情况
int tls13_send_client_certificate(TLS_CONNECT *conn) int tls13_send_client_certificate(TLS_CONNECT *conn)
{ {
int ret; int ret;
@@ -6126,6 +6199,46 @@ int tls13_send_client_finished(TLS_CONNECT *conn)
return 1; return 1;
} }
static int tls13_cipher_suites_match_signature_scheme(
const int *cipher_suites, size_t cipher_suites_cnt, int sig_alg,
int *selected, size_t *selected_cnt, size_t max_cnt)
{
int digest_oid;
size_t i;
switch (tls_signature_scheme_algorithm_oid(sig_alg)) {
case OID_sm2sign_with_sm3:
digest_oid = OID_sm3;
break;
case OID_ecdsa_with_sha256:
digest_oid = OID_sha256;
break;
default:
error_print();
return -1;
}
*selected_cnt = 0;
for (i = 0; i < cipher_suites_cnt && i < max_cnt; i++) {
const BLOCK_CIPHER *cipher;
const DIGEST *digest;
if (tls13_cipher_suite_get(cipher_suites[i], &cipher, &digest) != 1) {
error_print();
return -1;
}
if (digest->oid == digest_oid) {
selected[(*selected_cnt)++] = cipher_suites[i];
}
}
if (*selected_cnt == 0) {
return 0;
}
return 1;
}
int tls13_recv_client_hello(TLS_CONNECT *conn) int tls13_recv_client_hello(TLS_CONNECT *conn)
{ {
@@ -6242,6 +6355,7 @@ int tls13_recv_client_hello(TLS_CONNECT *conn)
} }
// cipher_suites // cipher_suites
// after select server cert_chain, cipher_suite might be changed
if ((ret = tls_cipher_suites_select(cipher_suites, cipher_suites_len, if ((ret = tls_cipher_suites_select(cipher_suites, cipher_suites_len,
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt, conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt,
&conn->cipher_suite)) < 0) { &conn->cipher_suite)) < 0) {
@@ -6254,11 +6368,6 @@ int tls13_recv_client_hello(TLS_CONNECT *conn)
return -1; return -1;
} }
tls13_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest);
// digest_update(client_hello) until conn->hello_retry_request
while (extslen) { while (extslen) {
int ext_type; int ext_type;
const uint8_t *ext_data; const uint8_t *ext_data;
@@ -6588,6 +6697,9 @@ int tls13_recv_client_hello(TLS_CONNECT *conn)
// * [server_name.host_name] // * [server_name.host_name]
// //
if (common_key_exchange_modes & TLS_KE_CERT_DHE) { if (common_key_exchange_modes & TLS_KE_CERT_DHE) {
int common_cipher_suites[4];
size_t common_cipher_suites_cnt;
if ((ret = tls13_cert_chains_select( if ((ret = tls13_cert_chains_select(
conn->ctx->cert_chains, conn->ctx->cert_chains_len, conn->ctx->cert_chains, conn->ctx->cert_chains_len,
common_sig_algs, common_sig_algs_cnt, common_sig_algs, common_sig_algs_cnt,
@@ -6603,8 +6715,39 @@ int tls13_recv_client_hello(TLS_CONNECT *conn)
error_print(); error_print();
common_key_exchange_modes &= ~TLS_KE_CERT_DHE; common_key_exchange_modes &= ~TLS_KE_CERT_DHE;
} }
// cipher_suites match conn->sig_alg
if (tls13_cipher_suites_match_signature_scheme(
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt, conn->sig_alg,
common_cipher_suites, &common_cipher_suites_cnt,
sizeof(common_cipher_suites)/sizeof(common_cipher_suites[0])) != 1) {
error_print();
return -1;
}
// update conn->cipher_suite
if ((ret = tls_cipher_suites_select(cipher_suites, cipher_suites_len,
common_cipher_suites, common_cipher_suites_cnt,
&conn->cipher_suite)) < 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_handshake_failure);
return -1;
}
} }
// format_print(stderr, 0, 0, "conn->cipher_suite: %s\n", tls_cipher_suite_name(conn->cipher_suite));
if (tls13_cipher_suite_get(conn->cipher_suite, &conn->cipher, &conn->digest) != 1) {
error_print();
return -1;
}
// digest_update(client_hello) until conn->hello_retry_request
// status_request // status_request
if (status_request) { if (status_request) {
int status_type; int status_type;
@@ -6823,6 +6966,7 @@ int tls13_recv_client_hello(TLS_CONNECT *conn)
error_print(); error_print();
return -1; return -1;
} }
format_bytes(stderr, 0, 0, "ClientHello", conn->record + 5, conn->recordlen - 5);
tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ClientHello", &conn->dgst_ctx);
} }
@@ -7357,6 +7501,7 @@ int tls13_send_server_hello(TLS_CONNECT *conn)
error_print(); error_print();
return -1; return -1;
} }
format_bytes(stderr, 0, 0, "ServerHello data", conn->record + 5, conn->recordlen - 5);
tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx); tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
if (tls13_generate_handshake_keys(conn) != 1) { if (tls13_generate_handshake_keys(conn) != 1) {
@@ -7390,6 +7535,9 @@ int tls13_send_alert(TLS_CONNECT *conn, int alert)
tls_record_set_protocol(conn->plain_record, TLS_protocol_tls12); tls_record_set_protocol(conn->plain_record, TLS_protocol_tls12);
tls_record_set_alert(conn->plain_record, &conn->plain_recordlen, TLS_alert_level_fatal, alert); tls_record_set_alert(conn->plain_record, &conn->plain_recordlen, TLS_alert_level_fatal, alert);
tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
switch (conn->state) { switch (conn->state) {
case TLS_handshake_client_hello: case TLS_handshake_client_hello:
case TLS_handshake_server_hello: case TLS_handshake_server_hello:
@@ -8052,6 +8200,9 @@ int tls13_send_early_data(TLS_CONNECT *conn)
conn->early_data_offset += sentlen; conn->early_data_offset += sentlen;
} }
conn->record_offset = 0;
conn->recordlen = 0;
return 1; return 1;
} }

View File

@@ -1599,6 +1599,8 @@ int x509_cert_get_subject_alt_name_dns_name(const uint8_t *a, size_t alen, const
{ {
const uint8_t *exts; const uint8_t *exts;
size_t extslen; size_t extslen;
const uint8_t *cp;
size_t len;
const uint8_t *general_names; const uint8_t *general_names;
size_t general_names_len; size_t general_names_len;
int choice = X509_gn_dns_name; int choice = X509_gn_dns_name;
@@ -1619,12 +1621,23 @@ int x509_cert_get_subject_alt_name_dns_name(const uint8_t *a, size_t alen, const
return 0; return 0;
} }
if ((ret = x509_exts_get_ext_by_oid(exts, extslen, OID_ce_subject_alt_name, if ((ret = x509_exts_get_ext_by_oid(exts, extslen, OID_ce_subject_alt_name,
&critical, &general_names, &general_names_len)) < 0) { &critical, &cp, &len)) < 0) {
error_print(); error_print();
return -1; return -1;
} else if (ret == 0) { } else if (ret == 0) {
return 0; return 0;
} }
if (asn1_sequence_from_der(&general_names, &general_names_len, &cp, &len) != 1) {
error_print();
return -1;
}
// x509_exts_get_ext_by_oid 这里取出的数据是一个SEQUENCE 的 TLV
// 然后x509_general_names_get_first 需要提供的是其中的V
format_bytes(stderr, 0, 0, "general_names", general_names, general_names_len);
if ((ret = x509_general_names_get_first(general_names, general_names_len, if ((ret = x509_general_names_get_first(general_names, general_names_len,
NULL, choice, dns_name, dns_name_len)) < 0) { NULL, choice, dns_name, dns_name_len)) < 0) {
error_print(); error_print();
@@ -1938,6 +1951,7 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
return -1; return -1;
} }
// 这个函数有点问题,如果不是SM2,那么是不需要signer_id的
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) { SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print(); error_print();
@@ -1953,6 +1967,10 @@ int x509_certs_verify(const uint8_t *certs, size_t certslen, int certs_type,
error_print(); error_print();
return -1; return -1;
} }
// 函数提供了一组根证书,我们要从根证书中找到和被验证的证书链匹配的那个根证书
// 如果没有找到对应的根证书,那么就会出错
// 但是这个错误隐藏在这个函数中并不合适!这说明这个函数的接口有问题
//
if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen, if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen,
&cacert, &cacertlen) != 1) { &cacert, &cacertlen) != 1) {
error_print(); error_print();

View File

@@ -1060,7 +1060,7 @@ int x509_general_names_get_first(const uint8_t *gns, size_t gns_len, const uint8
if ((ret = x509_general_names_get_next(gns, gns_len, &p, choice, d, dlen)) < 0) { if ((ret = x509_general_names_get_next(gns, gns_len, &p, choice, d, dlen)) < 0) {
error_print(); error_print();
return - 1; return -1;
} }
if (ptr) { if (ptr) {
@@ -1120,6 +1120,8 @@ int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, cons
format_print(fp, fmt, ind, "%s\n", label); format_print(fp, fmt, ind, "%s\n", label);
ind += 4; ind += 4;
format_bytes(fp, 0, 0, "der", d, dlen);
while (dlen) { while (dlen) {
if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) { if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) {
error_print(); error_print();

View File

@@ -16,6 +16,9 @@
#include <gmssl/tls.h> #include <gmssl/tls.h>
#include <gmssl/error.h> #include <gmssl/error.h>
// 检查密码参数和CA根证书是否适配
// 检查密码参数和客户端证书是否适配
static const char *http_get = static const char *http_get =
"GET / HTTP/1.1\r\n" "GET / HTTP/1.1\r\n"
@@ -365,7 +368,6 @@ bad:
error_print(); error_print();
return -1; return -1;
} }
error_print();
tls13_ctx_set_psk_key_exchange_modes(&ctx, psk_ke, psk_dhe_ke); tls13_ctx_set_psk_key_exchange_modes(&ctx, psk_ke, psk_dhe_ke);
} }
@@ -382,10 +384,12 @@ bad:
if (server_name) { if (server_name) {
error_print();
if (tls_set_server_name(&conn, (uint8_t *)host, strlen(host)) != 1) { if (tls_set_server_name(&conn, (uint8_t *)host, strlen(host)) != 1) {
error_print(); error_print();
goto end; goto end;
} }
fprintf(stderr, "conn->server_name= %d\n", conn.server_name);
} }
if (signature_algorithms_cert) { if (signature_algorithms_cert) {

View File

@@ -19,17 +19,9 @@
#include <gmssl/error.h> #include <gmssl/error.h>
/* // 服务器在启动时是否检查密码参数和证书适配的问题
如果采用PSK模式并且是外部密钥,那么意味着每个预置密钥关联一个cipher_suite // 服务器设置 -psk_dhe_ke,启动的时候没有检查是否提供了 supported_group 参数
那么ClientHello中的cipher_suites应该是这些套件的集合 // psk_cipher_suite 和 cipher_suite 是冗余的
但是ClientHello也可能支持PSK之外的套件,因此最终是常规cipher_suite + psk_cipher_suite的合集
我们需要多组证书,也就是 -cert -key -pass 构成一组,我们可以用一个数组把这些放到一起
*/
static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]"; static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]";
@@ -70,7 +62,7 @@ static const char *help =
" sm2sig_sm3\n" " sm2sig_sm3\n"
" ecdsa_secp256r1_sha256\n" " ecdsa_secp256r1_sha256\n"
"\n" "\n"
"Examples\n" "Generate SM2 certificates\n"
"\n" "\n"
" gmssl sm2keygen -pass 1234 -out sm2rootcakey.pem\n" " gmssl sm2keygen -pass 1234 -out sm2rootcakey.pem\n"
" gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 \\\n" " gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 \\\n"
@@ -80,26 +72,99 @@ static const char *help =
" gmssl sm2keygen -pass 1234 -out sm2cakey.pem\n" " gmssl sm2keygen -pass 1234 -out sm2cakey.pem\n"
" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"Sub CA\" \\\n" " gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"Sub CA\" \\\n"
" -key sm2cakey.pem -pass 1234 -out sm2careq.pem\n" " -key sm2cakey.pem -pass 1234 -out sm2careq.pem\n"
" gmssl reqsign -in sm2careq.pem -days 365 -key_usage keyCertSign -cacert rootcacert.pem -key rootcakey.pem -pass 1234 \\\n" " gmssl reqsign -in sm2careq.pem -days 365 -key_usage keyCertSign \\\n"
" -out sm2cacert.pem -ca -path_len_constraint 0\n" " -cacert sm2rootcacert.pem -key sm2rootcakey.pem -pass 1234 \\\n"
" -ca -path_len_constraint 0 \\\n"
" -out sm2cacert.pem\n"
"\n" "\n"
" gmssl sm2keygen -pass 1234 -out sm2signkey.pem\n" " gmssl sm2keygen -pass 1234 -out sm2signkey.pem\n"
" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -key sm2signkey.pem -pass 1234 -out sm2signreq.pem\n" " gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost \\\n"
" gmssl reqsign -in sm2signreq.pem -days 365 -key_usage digitalSignature -cacert sm2cacert.pem -key sm2cakey.pem -pass 1234 -out sm2signcert.pem\n" " -key sm2signkey.pem -pass 1234 -out sm2signreq.pem\n"
" gmssl reqsign -in sm2signreq.pem -days 365 -key_usage digitalSignature \\\n"
" -cacert sm2cacert.pem -key sm2cakey.pem -pass 1234 \\\n"
" -out sm2signcert.pem\n"
"\n" "\n"
" cat sm2signcert.pem > sm2certs.pem\n" " cat sm2signcert.pem > sm2certs.pem\n"
" cat sm2cacert.pem >> sm2certs.pem\n" " cat sm2cacert.pem >> sm2certs.pem\n"
"\n" "\n"
" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n" "TLS 1.3 with TLS_SM4_GCM_SM3 cipher suite\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n"
"\n"
"\n" "\n"
" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" " sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n" " -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n"
" -supported_group sm2p256v1 -supported_group prime256v1 \\\n"
" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256\n"
"\n" "\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n" " gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n"
"\n"
"Generate P-256 certificates\n"
"\n"
" gmssl p256keygen -pass 1234 -out p256rootcakey.pem\n"
" gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN P256ROOTCA -days 3650 \\\n"
" -key p256rootcakey.pem -pass 1234 -out p256rootcacert.pem \\\n"
" -key_usage keyCertSign -key_usage cRLSign -ca\n"
"\n"
" gmssl p256keygen -pass 1234 -out p256cakey.pem\n"
" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"P256 Sub CA\" \\\n"
" -key p256cakey.pem -pass 1234 -out p256careq.pem\n"
" gmssl reqsign -in p256careq.pem -days 365 -key_usage keyCertSign \\\n"
" -cacert p256rootcacert.pem -key p256rootcakey.pem -pass 1234 \\\n"
" -ca -path_len_constraint 0 \\\n"
" -out p256cacert.pem\n"
"\n"
" gmssl p256keygen -pass 1234 -out p256signkey.pem\n"
" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN 127.0.0.1 \\\n"
" -key p256signkey.pem -pass 1234 -out p256signreq.pem\n"
" gmssl reqsign -in p256signreq.pem -days 365 -key_usage digitalSignature \\\n"
" -cacert p256cacert.pem -key p256cakey.pem -pass 1234 \\\n"
" -subject_dns_name 127.0.0.1 \\\n"
" -out p256signcert.pem\n"
"\n"
" cat p256signcert.pem > p256certs.pem\n"
" cat p256cacert.pem >> p256certs.pem\n"
"\n"
" cat sm2rootcacert.pem > rootcacerts.pem\n"
" cat p256rootcacert.pem >> rootcacerts.pem\n"
"\n"
"TLS 1.3 with TLS_AES_128_GCM_SHA256\n"
" sudo gmssl tls13_server -port 4430 \\\n"
" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n"
" -cert p256certs.pem -key p256signkey.pem -pass 1234\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n"
" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n"
"\n"
"TLS 1.3 SNI\n"
"\n"
" sudo gmssl tls13_server -port 4430 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n"
" -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n"
" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n"
" -cert p256certs.pem -key p256signkey.pem -pass 1234 \\\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n"
" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256\n"
" -server_name\n"
"\n"
"HelloRetryRequest\n"
"\n"
" sudo gmssl tls13_server -port 4430 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n"
" -cert sm2certs.pem -key sm2signkey.pem -pass 1234\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n"
" -cipher_suite TLS_AES_128_GCM_SHA256 -supported_group prime256v1 -sig_alg ecdsa_secp256r1_sha256 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n"
" -max_key_exchanges 1 # or -max_key_exchanges 0 \n"
"\n"
"ClientHello with OCSP request, CT, and other extensions\n"
"\n"
" sudo gmssl tls13_server -port 4430 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n"
" -supported_group sm2p256v1 -supported_group prime256v1 \\\n"
" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n"
" -cert sm2certs.pem -key sm2signkey.pem -pass 1234\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n" " -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n"
" -supported_group sm2p256v1 -supported_group prime256v1 \\\n" " -supported_group sm2p256v1 -supported_group prime256v1 \\\n"
" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n" " -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n"
@@ -110,16 +175,20 @@ static const char *help =
" -post_handshake_auth \\\n" " -post_handshake_auth \\\n"
" -ct\n" " -ct\n"
"\n" "\n"
"NewSessionTicket\n"
"\n" "\n"
" TICKET_KEY=11223344556677881122334455667788\n" " TICKET_KEY=11223344556677881122334455667788\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" " sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" " -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n"
" -new_session_ticket 2 -ticket_key $TICKET_KEY\n" " -new_session_ticket 2 -ticket_key $TICKET_KEY\n"
"\n" "\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n" " gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacerts.pem \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n" " -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n"
" -sess_out session.bin\n" " -sess_out session.bin\n"
"\n" "\n"
"PSK-DHE from session ticket\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n" " sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n" " -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n"
" -psk_dhe_ke -ticket_key $TICKET_KEY\n" " -psk_dhe_ke -ticket_key $TICKET_KEY\n"
@@ -128,13 +197,33 @@ static const char *help =
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n" " -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n"
" -psk_dhe_ke -sess_in session.bin\n" " -psk_dhe_ke -sess_in session.bin\n"
"\n" "\n"
"PSK-DHE/PSK from external\n"
"\n" "\n"
" PSK=1122334455667788112233445566778811223344556677881122334455667788\n" " PSK=1122334455667788112233445566778811223344556677881122334455667788\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n"
" -supported_group sm2p256v1 -psk_dhe_ke \\\n"
" -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n"
" -supported_group sm2p256v1 -psk_dhe_ke \\\n"
" -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" " sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n"
" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" " -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n" " gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n"
" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n" " -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n"
"\n" "\n"
"EarlyData (0-RTT)\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n"
" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK \\\n"
" -early_data\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n"
" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK \\\n"
" -early_data early_data.txt\n"
"\n"; "\n";
int tls13_server_main(int argc , char **argv) int tls13_server_main(int argc , char **argv)
@@ -558,6 +647,10 @@ restart:
return -1; return -1;
} }
if (conn.early_data && conn.early_data_len) {
format_string(stderr, 0, 0, "EarlyData", conn.early_data_buf, conn.early_data_len);
}
for (;;) { for (;;) {
@@ -601,8 +694,6 @@ restart:
} }
for (;;) { for (;;) {
int rv; int rv;