Update TLS 1.3

This commit is contained in:
Zhi Guan
2026-04-21 11:18:25 +08:00
parent 0bcffd3734
commit 34698ddc6f
13 changed files with 4602 additions and 3587 deletions

View File

@@ -128,6 +128,11 @@ set(src
src/socket.c
src/tls.c
src/tls_ext.c
src/tls_psk.c
src/tls_sni.c
src/tls_sct.c
src/tls_ocsp.c
src/tls_cookie.c
src/tls_trace.c
src/tlcp.c
src/tls12.c

File diff suppressed because it is too large Load Diff

157
src/tls.c
View File

@@ -1,4 +1,4 @@
/*
/*
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
@@ -264,7 +264,7 @@ int tls_record_set_protocol(uint8_t *record, int protocol)
return 1;
}
int tls_record_set_length(uint8_t *record, size_t length)
int tls_record_set_data_length(uint8_t *record, size_t length)
{
uint8_t *p = record + 3;
size_t len;
@@ -278,7 +278,7 @@ int tls_record_set_length(uint8_t *record, size_t length)
int tls_record_set_data(uint8_t *record, const uint8_t *data, size_t datalen)
{
if (tls_record_set_length(record, datalen) != 1) {
if (tls_record_set_data_length(record, datalen) != 1) {
error_print();
return -1;
}
@@ -1558,8 +1558,6 @@ int tls_cipher_suite_support_protocol(int cipher, int protocol)
return 1;
}
/*
尽可能的发送数据直到发送完整的报文或者send 返回错误
如果send 返回EAGAIN那么向上层返回WANT_WRITE
@@ -1568,9 +1566,6 @@ int tls_cipher_suite_support_protocol(int cipher, int protocol)
send会返回EAGIN那么如果底层没处理完那就没有任何办法
如果这个函数在获得EAGAIN之后就返回给上层了那么还需要标明到底发送出去了多少数据
*/
int tls_record_send(const uint8_t *record, size_t recordlen, tls_socket_t sock)
{
@@ -2241,14 +2236,10 @@ int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client)
memcpy(ctx->supported_versions, supported_versions, sizeof(supported_versions));
ctx->supported_versions_cnt = sizeof(supported_versions)/sizeof(supported_versions[0]);
// 这个参数应该在设置证书的时候再设定
ctx->verify_depth = 5;
// key_share
ctx->key_exchanges_cnt = 2;
return 1;
}
@@ -2307,6 +2298,7 @@ int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cip
return 1;
}
/*
int tls_ctx_set_key_exchange_modes(TLS_CTX *ctx, int modes)
{
if (!ctx) {
@@ -2322,6 +2314,7 @@ int tls_ctx_set_key_exchange_modes(TLS_CTX *ctx, int modes)
return 1;
}
*/
// 这个函数不是很好,直接提供的是一个文件名
int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth)
@@ -2355,12 +2348,9 @@ int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth
return 1;
}
// 这个函数需要设置一个默认的证书链
// 这个函数实际上是有问题的没有给这个证书链提供status_request和sct_list
// cert_chain的格式到底是什么呢
// 是单独的证书链,还是也包含扩展呢?
int tls_ctx_add_certificate_chain_and_key(TLS_CTX *ctx, const char *chainfile,
int tls_ctx_add_certificate_list_and_key(TLS_CTX *ctx, const char *chainfile,
const uint8_t *entity_status_request_ocsp_response, size_t entity_status_request_ocsp_response_len, // optional
const uint8_t *entity_signed_certificate_timestamp_list, size_t entity_signed_certificate_timestamp_list_len, // optional
const char *keyfile, const char *keypass)
{
uint8_t *cert_chain;
@@ -2371,39 +2361,73 @@ int tls_ctx_add_certificate_chain_and_key(TLS_CTX *ctx, const char *chainfile,
X509_KEY public_key;
FILE *keyfp = NULL;
uint8_t *ocsp_responses;
size_t ocsp_responses_len;
uint8_t *sct_lists;
size_t sct_lists_len;
if (!ctx || !chainfile || !keyfile || !keypass) {
error_print();
return -1;
}
// no space in ctx->cert_chains[]
// status_request
ocsp_responses_len = ctx->status_request_ocsp_responses_len;
tls_uint24array_to_bytes(
entity_status_request_ocsp_response,
entity_status_request_ocsp_response_len,
NULL, &ocsp_responses_len);
if (ocsp_responses_len > sizeof(ctx->status_request_ocsp_responses)) {
error_print();
return -1;
}
ocsp_responses = ctx->status_request_ocsp_responses;
tls_uint24array_to_bytes(
entity_status_request_ocsp_response,
entity_status_request_ocsp_response_len,
&ocsp_responses,
&ctx->status_request_ocsp_responses_len);
// signed_certificate_timestamp
sct_lists_len = ctx->signed_certificate_timestamp_lists_len;
tls_uint16array_to_bytes(
entity_signed_certificate_timestamp_list,
entity_signed_certificate_timestamp_list_len,
NULL, &sct_lists_len);
if (sct_lists_len > sizeof(ctx->signed_certificate_timestamp_lists)) {
error_print();
return -1;
}
sct_lists = ctx->signed_certificate_timestamp_lists;
tls_uint16array_to_bytes(
entity_signed_certificate_timestamp_list,
entity_signed_certificate_timestamp_list_len,
&sct_lists, &ctx->signed_certificate_timestamp_lists_len);
// add cert_chain to ctx->cert_chains
if (sizeof(ctx->cert_chains) <= ctx->cert_chains_len + tls_uint24_size()) {
error_print();
return -1;
}
// no space in ctx->x509_keys[]
if (sizeof(ctx->x509_keys)/sizeof(ctx->x509_keys[0]) <= ctx->x509_keys_cnt) {
error_print();
return -1;
}
if (!(certfp = fopen(chainfile, "r"))) {
error_print();
return -1;
}
// read and save cert_chain as uint24array
cert_chain = ctx->cert_chains + ctx->cert_chains_len;
cert_chain = ctx->cert_chains + ctx->cert_chains_len ;
if (x509_certs_from_pem(cert_chain + tls_uint24_size(), &cert_chain_len,
sizeof(ctx->cert_chains) - ctx->cert_chains_len - tls_uint24_size(),
certfp) != 1) {
sizeof(ctx->cert_chains) - ctx->cert_chains_len - tls_uint24_size(), certfp) != 1) {
error_print();
return -1;
}
tls_uint24_to_bytes(cert_chain_len, &cert_chain, &cert_chain_len);
ctx->cert_chains_len += cert_chain_len;
cert_chain_len -= tls_uint24_size();
// add private key to ctx->x509_keys
if (sizeof(ctx->x509_keys)/sizeof(ctx->x509_keys[0]) <= ctx->x509_keys_cnt) {
error_print();
return -1;
}
if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
fclose(certfp);
@@ -2423,8 +2447,6 @@ int tls_ctx_add_certificate_chain_and_key(TLS_CTX *ctx, const char *chainfile,
return -1;
}
}
// read and save at most two keys as uint16array
if (x509_private_key_from_file(&ctx->x509_keys[ctx->x509_keys_cnt], public_key.algor, keypass, keyfp) != 1) {
fclose(certfp);
fclose(keyfp);
@@ -2433,11 +2455,25 @@ int tls_ctx_add_certificate_chain_and_key(TLS_CTX *ctx, const char *chainfile,
}
ctx->x509_keys_cnt++;
// TODO: if the second cert is entity's sm2 encryption cert, try to read private key from keyfp
fclose(certfp);
fclose(keyfp);
return 1;
}
int tls_ctx_add_certificate_chain_and_key(TLS_CTX *ctx, const char *chainfile,
const char *keyfile, const char *keypass)
{
if (tls_ctx_add_certificate_list_and_key(ctx, chainfile, NULL, 0, NULL, 0, keyfile, keypass) != 1) {
error_print();
return -1;
}
return 1;
}
// 保留这个函数,相当于是对证书链的初始化
int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile,
const char *keyfile, const char *keypass)
@@ -2615,6 +2651,8 @@ 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;
}
@@ -2676,6 +2714,8 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx)
memset(conn, 0, sizeof(*conn));
conn->is_client = ctx->is_client;
conn->protocol = ctx->protocol;
@@ -2725,15 +2765,34 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx)
conn->new_session_ticket = ctx->new_session_ticket;
conn->key_exchange_modes = ctx->key_exchange_modes;
// init 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 (!conn->key_exchange_modes) {
error_print();
return -1;
}
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;
// pre_shared_key
if (conn->key_exchange_modes & (TLS_KE_PSK_DHE|TLS_KE_PSK)) {
conn->pre_shared_key = 1;
}
return 1;
}
@@ -2819,8 +2878,12 @@ int tls_uint16array_from_file(uint8_t *arr, size_t *arrlen, size_t maxlen, FILE
}
if (fread(arr, 1, 2, fp) != 2) {
error_print();
return -1;
if (feof(fp)) {
return 0;
} else {
error_print();
return -1;
}
}
cp = arr;
len = 2;
@@ -2841,23 +2904,5 @@ int tls_uint16array_from_file(uint8_t *arr, size_t *arrlen, size_t maxlen, FILE
return 1;
}
int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host_name_len)
{
if (!conn || !host_name || !host_name_len) {
error_print();
return -1;
}
if (!conn->is_client) {
error_print();
return -1;
}
if (host_name_len >= sizeof(conn->server_name)) {
error_print();
return -1;
}
memcpy(conn->server_name, host_name, host_name_len);
conn->server_name[host_name_len] = 0;
conn->server_name_len = host_name_len;
return 1;
}

View File

@@ -196,107 +196,6 @@ int tls_named_curve_from_oid(int oid)
/*
session_ticket_key
* server_only
* server encrypt and send NewSessionTicket
* server decrypt ClientHello.pre_shared_key
*/
int tls13_ctx_set_session_ticket_key(TLS_CTX *ctx, const uint8_t *key, size_t keylen)
{
if (!ctx || !key || !keylen) {
error_print();
return -1;
}
if (ctx->is_client) {
error_print();
return -1;
}
if (keylen != SM4_KEY_SIZE) {
error_print();
return -1;
}
sm4_set_encrypt_key(&ctx->_session_ticket_key, key);
ctx->session_ticket_key = &ctx->_session_ticket_key;
return 1;
}
#define TLS_MAX_NEW_SESSION_TICKETS 5
int tls13_ctx_set_new_session_ticket(TLS_CTX *ctx, size_t new_session_ticket_cnt)
{
if (!ctx) {
error_print();
return -1;
}
if (new_session_ticket_cnt > TLS_MAX_NEW_SESSION_TICKETS) {
error_print();
return -1;
}
ctx->new_session_ticket = (int)new_session_ticket_cnt;
return 1;
}
int tls13_set_new_session_ticket(TLS_CONNECT *conn, size_t new_session_ticket_cnt)
{
if (!conn) {
error_print();
return -1;
}
if (new_session_ticket_cnt > TLS_MAX_NEW_SESSION_TICKETS) {
error_print();
return -1;
}
conn->new_session_ticket = new_session_ticket_cnt;
return 1;
}
// 这两个函数还有用吗?
/*
int tls13_set_session_infile(TLS_CONNECT *conn, const char *file)
{
if (!conn || !file) {
error_print();
return -1;
}
if (!conn->is_client) {
error_print();
return -1;
}
conn->session_in = file;
return 1;
}
*/
int tls13_set_session_outfile(TLS_CONNECT *conn, const char *file)
{
if (!conn || !file) {
error_print();
return -1;
}
if (!conn->is_client) {
error_print();
return -1;
}
conn->session_out = file;
return 1;
}
@@ -2876,420 +2775,3 @@ int tls12_do_accept(TLS_CONNECT *conn)
return 1;
}
/*
status_request(5)
这个扩展在客户端和服务器端中是不同的
ClientHello.status_request
struct {
CertificateStatusType status_type = ocsp(1);
opaque request<0..2^16-1>;
} CertificateStatusRequest;
其中request中是
struct {
ResponderID responder_id_list<0..2^16-1>;
Extensions request_extensions;
} OCSPStatusRequest;
------------------------------------------------------
server Certificate
struct {
CertificateStatusType status_type;
opaque response<1..2^24-1>;
} CertificateStatus;
response中的数据是就是一个原始的OCSP的response我们将其视为二进制数据
在TLS 1.2中如果服务器同意status_request会在ServerHello中返回一个空的status_request
并且会返回一个独立的CertificateStatus握手消息
*/
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,
uint8_t **out, size_t *outlen)
{
uint8_t **pp = out;
size_t request_len = 0;
size_t len;
if (!outlen) {
error_print();
return -1;
}
tls_uint16_to_bytes(0, out, &len);
tls_uint16array_to_bytes(responder_id_list, responder_id_list_len, out, &request_len);
tls_uint16array_to_bytes(request_exts, request_exts_len, out, &request_len);
tls_uint16array_to_bytes(NULL, request_len, pp, outlen);
return 1;
}
int tls_ocsp_status_request_from_bytes(
const uint8_t **responder_id_list, size_t *responder_id_list_len,
const uint8_t **request_exts, size_t *request_exts_len,
const uint8_t **in, size_t *inlen)
{
const uint8_t *request;
size_t request_len;
if (!responder_id_list || !responder_id_list_len || !request_exts || !request_exts_len
|| !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_uint16array_from_bytes(&request, &request_len, in, inlen) != 1) {
error_print();
return -1;
}
if (!request) {
*responder_id_list = NULL;
*responder_id_list_len = 0;
*request_exts = NULL;
*request_exts_len = 0;
return 1;
}
if (tls_uint16array_from_bytes(responder_id_list, responder_id_list_len, &request, &request_len) != 1
|| tls_uint16array_from_bytes(request_exts, request_exts_len, &request, &request_len) != 1
|| tls_length_is_zero(request_len) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_ocsp_status_request_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *ext_data, size_t ext_datalen)
{
const uint8_t *request;
size_t request_len;
const uint8_t *responder_id_list;
size_t responder_id_list_len;
const uint8_t *request_exts;
size_t request_exts_len;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if (tls_uint16array_from_bytes(&request, &request_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
if (!request) {
format_print(fp, fmt, ind, "(null)\n");
if (ext_datalen) {
format_print(fp, fmt, ind, "error: left %zu bytes\n", ext_datalen);
return -1;
}
return 1;
}
if (tls_uint16array_from_bytes(&responder_id_list, &responder_id_list_len, &request, &request_len) != 1
|| tls_uint16array_from_bytes(&request_exts, &request_exts_len, &request, &request_len) != 1) {
error_print();
return -1;
}
while (responder_id_list_len) {
const uint8_t *responder_id;
size_t responder_id_len;
if (tls_uint16array_from_bytes(&responder_id, &responder_id_len,
&responder_id_list, &responder_id_list_len) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, ind + 4, "ResponderID", responder_id, responder_id_len);
}
while (request_exts_len) {
int ext_type;
const uint8_t *ext_data;
size_t ext_datalen;
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &request_exts, &request_exts_len) != 1) {
error_print();
return -1;
}
// print
}
return 1;
}
/*
struct {
CertificateStatusType status_type = ocsp(1);
opaque request<0..2^16-1>;
} CertificateStatusRequest;
*/
int tls_client_status_request_ext_to_bytes(int status_type,
const uint8_t *responder_id_list, size_t responder_id_list_len,
const uint8_t *request_exts, size_t request_exts_len,
uint8_t **out, size_t *outlen)
{
int ext_type = TLS_extension_status_request;
size_t ext_datalen = 0;
uint8_t **pp = out;
size_t len;
if (!outlen) {
error_print();
return -1;
}
tls_ext_to_bytes(ext_type, NULL, 0, out, &len);
tls_uint8_to_bytes(status_type, out, &ext_datalen);
tls_ocsp_status_request_to_bytes(responder_id_list, responder_id_list_len,
request_exts, request_exts_len, out, &ext_datalen);
tls_ext_to_bytes(ext_type, NULL, ext_datalen, pp, outlen);
return 1;
}
int tls_client_status_request_from_bytes(int *status_type,
const uint8_t **responder_id_list, size_t *responder_id_list_len,
const uint8_t **request_exts, size_t *request_exts_len,
const uint8_t *ext_data, size_t ext_datalen)
{
uint8_t status;
if (!status_type || !responder_id_list || !responder_id_list_len
|| !request_exts || !request_exts_len || !ext_data || !ext_datalen) {
error_print();
return -1;
}
if (tls_uint8_from_bytes(&status, &ext_data, &ext_datalen) != 1
|| tls_ocsp_status_request_from_bytes(responder_id_list, responder_id_list_len,
request_exts, request_exts_len, &ext_data, &ext_datalen) != 1
|| tls_length_is_zero(ext_datalen) != 1) {
error_print();
return -1;
}
*status_type = status;
return 1;
}
int tls_client_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
{
uint8_t status_type;
const uint8_t *request;
size_t request_len;
if (tls_uint8_from_bytes(&status_type, &ext_data, &ext_datalen) != 1
|| tls_uint16array_from_bytes(&request, &request_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "status_type: %s (%d)\n", status_type == TLS_certificate_status_type_ocsp ? "ocsp" : NULL, status_type);
request -= tls_uint16_size();
request_len += tls_uint16_size();
tls_ocsp_status_request_print(fp, fmt, ind, "request", request, request_len);
return 1;
}
//----------------------------------------------------------------------------
int ocsp_response_verify(const uint8_t *ocsp_response, size_t ocsp_response_len,
const uint8_t *ca_certs, size_t ca_certs_len)
{
return 1;
}
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 ext_type = TLS_extension_status_request;
size_t ext_datalen = 0;
uint8_t **pp = out;
size_t len;
if (!ocsp_response || !ocsp_response_len || !outlen) {
error_print();
return -1;
}
tls_ext_to_bytes(ext_type, NULL, 0, out, &len);
tls_uint24array_to_bytes(ocsp_response, ocsp_response_len, out, &ext_datalen);
tls_ext_to_bytes(ext_type, NULL, ext_datalen, pp, outlen);
return 1;
}
int tls_server_status_request_from_bytes(const uint8_t **ocsp_response, size_t *ocsp_response_len,
const uint8_t *ext_data, size_t ext_datalen)
{
if (!ocsp_response || !ocsp_response_len || !ext_data || !ext_datalen) {
error_print();
return -1;
}
if (tls_uint24array_from_bytes(ocsp_response, ocsp_response_len, &ext_data, &ext_datalen) != 1
|| tls_length_is_zero(ext_datalen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_server_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
{
const uint8_t *ocsp_response;
size_t ocsp_response_len;
if (tls_uint24array_from_bytes(&ocsp_response, &ocsp_response_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, ind, "ocsp_response", ocsp_response, ocsp_response_len);
if (ext_datalen) {
error_print();
return -1;
}
return 1;
}
/*
signed_certificate_timestamp
struct {
opaque sct_list<1..2^16-1>;
} SignedCertificateTimestampList;
*/
/*
signed_certificate_timestamp (CT)
这是一个tls13的扩展
这个扩展只在ServerCertificate, ClientCertificate握手消息的扩展中
这个扩展主要是提供一个格外的信息:
证书透明度CT日志服务器签发的“证书存在证明”的扩展。
struct {
opaque key_id[32]; // 日志服务器ID
uint64 timestamp; // 证书提交时间戳
opaque signature<0..2^16-1>; // 日志服务器签名
} SignedCertificateTimestamp;
struct {
SignedCertificateTimestamp sct_list<0..2^16-1>;
} SignedCertificateTimestampList;
*/
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)
{
if (!key_id || !signature || !signature_len || !outlen) {
error_print();
return -1;
}
tls_array_to_bytes(key_id, 32, out, outlen);
tls_uint64_to_bytes(timestamp, out, outlen);
tls_uint16array_to_bytes(signature, signature_len, out, outlen);
return 1;
}
int tls_signed_certificate_timestamp_entry_from_bytes(const uint8_t **key_id,
uint64_t *timestamp, const uint8_t **signature, size_t *signature_len,
const uint8_t **in, size_t *inlen)
{
if (!key_id || !timestamp || !signature || !signature_len || !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_array_from_bytes(key_id, 32, in, inlen) != 1
|| tls_uint64_from_bytes(timestamp, in, inlen) != 1
|| tls_uint16array_from_bytes(signature, signature_len, in, inlen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_signed_certificate_timestamp_ext_to_bytes(const uint8_t *sct_list, size_t sct_list_len,
uint8_t **out, size_t *outlen)
{
if (!sct_list || !sct_list_len || !outlen) {
error_print();
return -1;
}
tls_uint16array_to_bytes(sct_list, sct_list_len, out, outlen);
return 1;
}
int tls_signed_certificate_timestamp_from_bytes(const uint8_t **sct_list, size_t *sct_list_len,
const uint8_t **in, size_t *inlen)
{
if (!sct_list || !sct_list_len || !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_uint16array_from_bytes(sct_list, sct_list_len, in, inlen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_signed_certificate_timestamp_print(FILE *fp, int fmt, int ind,
const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *sct_list;
size_t sct_list_len;
if (tls_uint16array_from_bytes(&sct_list, &sct_list_len, &d, &dlen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "sct_list\n");
ind += 4;
if (!sct_list_len) {
format_print(fp, fmt, ind, "(null)\n");
}
while (sct_list_len) {
const uint8_t *key_id;
uint64_t timestamp;
const uint8_t *signature;
size_t signature_len;
int entry_ind = ind + 4;
format_print(fp, fmt, ind, "SignedCertificateTimestamp\n");
if (tls_array_from_bytes(&key_id, 32, &sct_list, &sct_list_len) != 1
|| tls_uint64_from_bytes(&timestamp, &sct_list, &sct_list_len) != 1
|| tls_uint16array_from_bytes(&signature, &signature_len, &sct_list, &sct_list_len) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, entry_ind, "key_id", key_id, 32);
format_print(fp, fmt, entry_ind, "timestamp: %"PRIu64"\n", timestamp);
format_bytes(fp, fmt, entry_ind, "signature", signature, signature_len);
if (dlen) {
error_print();
return -1;
}
}
return 1;
}

File diff suppressed because it is too large Load Diff

126
src/tls_cookie.c Normal file
View File

@@ -0,0 +1,126 @@
/*
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <gmssl/rand.h>
#include <gmssl/x509.h>
#include <gmssl/error.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
#include <gmssl/pem.h>
#include <gmssl/mem.h>
#include <gmssl/tls.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/select.h>
/*
cookie
* server HelloRetryReqeust
* client ClientHello (again)
struct {
opaque cookie<1..2^16-1>;
} Cookie;
*/
int tls13_cookie_generate(const SM4_KEY *cookie_key, // server_ctx->cookie_key
const uint8_t *client_info, size_t client_info_len,
uint8_t *cookie, size_t *cookie_len)
{
rand_bytes(cookie, 32);
*cookie_len = 32;
return 1;
}
int tls13_cookie_verify(const SM4_KEY *cookie_key, // server_ctx->cookie_key
const uint8_t *client_info, size_t client_info_len,
const uint8_t *cookie, size_t cookie_len)
{
return 1;
}
int tls13_cookie_ext_to_bytes(const uint8_t *cookie, size_t cookielen, uint8_t **out, size_t *outlen)
{
uint16_t ext_type = TLS_extension_cookie;
size_t ext_datalen;
if (!cookie || !cookielen || cookielen > 65535) {
error_print();
return -1;
}
ext_datalen = 2 + cookielen;
if (ext_datalen > 65535) {
error_print();
return -1;
}
tls_uint16_to_bytes(ext_type, out, outlen);
tls_uint16_to_bytes((uint16_t)ext_datalen, out, outlen);
tls_uint16array_to_bytes(cookie, cookielen, out, outlen);
return 1;
}
int tls13_cookie_from_bytes(const uint8_t **cookie, size_t *cookielen, const uint8_t *ext_data, size_t ext_datalen)
{
if (tls_uint16array_from_bytes(cookie, cookielen, &ext_data, &ext_datalen) != 1
|| tls_length_is_zero(ext_datalen) != 1) {
error_print();
return -1;
}
if (!(*cookie) || !(*cookielen)) {
error_print();
return -1;
}
return 1;
}
int tls13_cookie_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
{
const uint8_t *cookie;
size_t cookielen;
if (tls_uint16array_from_bytes(&cookie, &cookielen, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, ind, "cookie", cookie, cookielen);
if (ext_datalen) {
error_print();
return -1;
}
return 1;
}
// if server send cookie in HelloRetryRequest, client must return cookie in ClientHello2
// so server conn follows cookie setting from ctx, client conn behaves passively
int tls13_ctx_set_cookie_key(TLS_CTX *ctx, const uint8_t *cookie_key, size_t cookie_key_len)
{
if (!ctx || !cookie_key || !cookie_key_len) {
error_print();
return -1;
}
if (cookie_key_len != SM4_KEY_SIZE) {
error_print();
return -1;
}
sm4_set_encrypt_key(&ctx->cookie_key, cookie_key);
ctx->cookie = 1;
return 1;
}

327
src/tls_ocsp.c Normal file
View File

@@ -0,0 +1,327 @@
/*
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <gmssl/rand.h>
#include <gmssl/x509.h>
#include <gmssl/error.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
#include <gmssl/pem.h>
#include <gmssl/mem.h>
#include <gmssl/tls.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/select.h>
/*
status_request(5)
ClientHello.status_request
ext_data := CertificateStatusRequest;
struct {
uint8 status_type = ocsp(1);
opaque request<0..2^16-1>;
} CertificateStatusRequest;
request.data := OCSPStatusRequest;
struct {
ResponderID responder_id_list<0..2^16-1>;
Extensions request_extensions;
} 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
uint8_t **out, size_t *outlen)
{
uint8_t **pp = out;
size_t request_len = 0;
size_t len;
if (!outlen) {
error_print();
return -1;
}
tls_uint16_to_bytes(0, out, &len);
tls_uint16array_to_bytes(responder_id_list, responder_id_list_len, out, &request_len);
tls_uint16array_to_bytes(request_exts, request_exts_len, out, &request_len);
tls_uint16array_to_bytes(NULL, request_len, pp, outlen);
return 1;
}
int tls_ocsp_status_request_from_bytes(
const uint8_t **responder_id_list, size_t *responder_id_list_len,
const uint8_t **request_exts, size_t *request_exts_len,
const uint8_t **in, size_t *inlen)
{
const uint8_t *request;
size_t request_len;
if (!responder_id_list || !responder_id_list_len || !request_exts || !request_exts_len
|| !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_uint16array_from_bytes(&request, &request_len, in, inlen) != 1) {
error_print();
return -1;
}
if (!request) {
*responder_id_list = NULL;
*responder_id_list_len = 0;
*request_exts = NULL;
*request_exts_len = 0;
return 1;
}
if (tls_uint16array_from_bytes(responder_id_list, responder_id_list_len, &request, &request_len) != 1
|| tls_uint16array_from_bytes(request_exts, request_exts_len, &request, &request_len) != 1
|| tls_length_is_zero(request_len) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_ocsp_status_request_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *ext_data, size_t ext_datalen)
{
const uint8_t *request;
size_t request_len;
const uint8_t *responder_id_list;
size_t responder_id_list_len;
const uint8_t *request_exts;
size_t request_exts_len;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if (tls_uint16array_from_bytes(&request, &request_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
if (!request) {
format_print(fp, fmt, ind, "(null)\n");
if (ext_datalen) {
format_print(fp, fmt, ind, "error: left %zu bytes\n", ext_datalen);
return -1;
}
return 1;
}
if (tls_uint16array_from_bytes(&responder_id_list, &responder_id_list_len, &request, &request_len) != 1
|| tls_uint16array_from_bytes(&request_exts, &request_exts_len, &request, &request_len) != 1) {
error_print();
return -1;
}
while (responder_id_list_len) {
const uint8_t *responder_id;
size_t responder_id_len;
if (tls_uint16array_from_bytes(&responder_id, &responder_id_len,
&responder_id_list, &responder_id_list_len) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, ind + 4, "ResponderID", responder_id, responder_id_len);
}
while (request_exts_len) {
int ext_type;
const uint8_t *ext_data;
size_t ext_datalen;
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &request_exts, &request_exts_len) != 1) {
error_print();
return -1;
}
// print
}
return 1;
}
int tls_client_status_request_ext_to_bytes(int status_type,
const uint8_t *responder_id_list, size_t responder_id_list_len,
const uint8_t *request_exts, size_t request_exts_len,
uint8_t **out, size_t *outlen)
{
int ext_type = TLS_extension_status_request;
size_t ext_datalen = 0;
uint8_t **pp = out;
size_t len;
if (!outlen) {
error_print();
return -1;
}
if (status_type != TLS_certificate_status_type_ocsp) {
error_print();
return -1;
}
tls_ext_to_bytes(ext_type, NULL, 0, out, &len);
tls_uint8_to_bytes(status_type, out, &ext_datalen);
tls_ocsp_status_request_to_bytes(responder_id_list, responder_id_list_len,
request_exts, request_exts_len, out, &ext_datalen);
tls_ext_to_bytes(ext_type, NULL, ext_datalen, pp, outlen);
return 1;
}
int tls_client_status_request_from_bytes(int *status_type,
const uint8_t **responder_id_list, size_t *responder_id_list_len,
const uint8_t **request_exts, size_t *request_exts_len,
const uint8_t *ext_data, size_t ext_datalen)
{
uint8_t status;
if (!status_type || !responder_id_list || !responder_id_list_len
|| !request_exts || !request_exts_len || !ext_data || !ext_datalen) {
error_print();
return -1;
}
if (tls_uint8_from_bytes(&status, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
if (status != TLS_certificate_status_type_ocsp) {
error_print();
return -1;
}
*status_type = status;
if (tls_ocsp_status_request_from_bytes(responder_id_list, responder_id_list_len,
request_exts, request_exts_len, &ext_data, &ext_datalen) != 1
|| tls_length_is_zero(ext_datalen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_client_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
{
uint8_t status_type;
const uint8_t *request;
size_t request_len;
if (tls_uint8_from_bytes(&status_type, &ext_data, &ext_datalen) != 1
|| tls_uint16array_from_bytes(&request, &request_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "status_type: %s (%d)\n", status_type == TLS_certificate_status_type_ocsp ? "ocsp" : NULL, status_type);
request -= tls_uint16_size();
request_len += tls_uint16_size();
tls_ocsp_status_request_print(fp, fmt, ind, "request", request, request_len);
return 1;
}
/*
Certificate.certificate_list.CertificateEntry.status_request
ext_data := CertificateStatus;
struct {
CertificateStatusType status_type;
opaque response<1..2^24-1>;
} CertificateStatus;
*/
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 ext_type = TLS_extension_status_request;
size_t ext_datalen = 0;
uint8_t **pp = out;
size_t len;
if (!ocsp_response || !ocsp_response_len || !outlen) {
error_print();
return -1;
}
tls_ext_to_bytes(ext_type, NULL, 0, out, &len);
tls_uint24array_to_bytes(ocsp_response, ocsp_response_len, out, &ext_datalen);
tls_ext_to_bytes(ext_type, NULL, ext_datalen, pp, outlen);
return 1;
}
int tls_server_status_request_from_bytes(const uint8_t **ocsp_response, size_t *ocsp_response_len,
const uint8_t *ext_data, size_t ext_datalen)
{
if (!ocsp_response || !ocsp_response_len || !ext_data || !ext_datalen) {
error_print();
return -1;
}
if (tls_uint24array_from_bytes(ocsp_response, ocsp_response_len, &ext_data, &ext_datalen) != 1
|| tls_length_is_zero(ext_datalen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_server_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
{
const uint8_t *ocsp_response;
size_t ocsp_response_len;
if (tls_uint24array_from_bytes(&ocsp_response, &ocsp_response_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, ind, "ocsp_response", ocsp_response, ocsp_response_len);
if (ext_datalen) {
error_print();
return -1;
}
return 1;
}
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
{
if (!conn) {
error_print();
return -1;
}
if (!conn->is_client) {
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;
return 1;
}
int ocsp_response_verify(const uint8_t *ocsp_response, size_t ocsp_response_len,
const uint8_t *ca_certs, size_t ca_certs_len)
{
return 1;
}
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)
{
return 1;
}

1942
src/tls_psk.c Normal file

File diff suppressed because it is too large Load Diff

165
src/tls_sct.c Normal file
View File

@@ -0,0 +1,165 @@
/*
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <gmssl/rand.h>
#include <gmssl/x509.h>
#include <gmssl/error.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
#include <gmssl/pem.h>
#include <gmssl/mem.h>
#include <gmssl/tls.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/select.h>
/*
ClientHello.exts.signed_certificate_timestamp
ext_data := empty
*/
/*
Certificate.certificate_list.CertificateEntry.exts.signed_certificate_timestamp
ext_data := SignedCertificateTimestamp sct_list<0..2^16-1>;
struct {
opaque key_id[32];
uint64 timestamp;
opaque signature<0..2^16-1>;
} SignedCertificateTimestamp;
*/
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)
{
if (!key_id || !signature || !signature_len || !outlen) {
error_print();
return -1;
}
tls_array_to_bytes(key_id, 32, out, outlen);
tls_uint64_to_bytes(timestamp, out, outlen);
tls_uint16array_to_bytes(signature, signature_len, out, outlen);
return 1;
}
int tls_signed_certificate_timestamp_entry_from_bytes(const uint8_t **key_id,
uint64_t *timestamp, const uint8_t **signature, size_t *signature_len,
const uint8_t **in, size_t *inlen)
{
if (!key_id || !timestamp || !signature || !signature_len || !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_array_from_bytes(key_id, 32, in, inlen) != 1
|| tls_uint64_from_bytes(timestamp, in, inlen) != 1
|| tls_uint16array_from_bytes(signature, signature_len, in, inlen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_signed_certificate_timestamp_ext_to_bytes(const uint8_t *sct_list, size_t sct_list_len,
uint8_t **out, size_t *outlen)
{
if (!sct_list || !sct_list_len || !outlen) {
error_print();
return -1;
}
tls_uint16array_to_bytes(sct_list, sct_list_len, out, outlen);
return 1;
}
int tls_signed_certificate_timestamp_from_bytes(const uint8_t **sct_list, size_t *sct_list_len,
const uint8_t **in, size_t *inlen)
{
if (!sct_list || !sct_list_len || !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_uint16array_from_bytes(sct_list, sct_list_len, in, inlen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_signed_certificate_timestamp_print(FILE *fp, int fmt, int ind,
const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *sct_list;
size_t sct_list_len;
if (tls_uint16array_from_bytes(&sct_list, &sct_list_len, &d, &dlen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "sct_list\n");
ind += 4;
if (!sct_list_len) {
format_print(fp, fmt, ind, "(null)\n");
}
while (sct_list_len) {
const uint8_t *key_id;
uint64_t timestamp;
const uint8_t *signature;
size_t signature_len;
int entry_ind = ind + 4;
format_print(fp, fmt, ind, "SignedCertificateTimestamp\n");
if (tls_array_from_bytes(&key_id, 32, &sct_list, &sct_list_len) != 1
|| tls_uint64_from_bytes(&timestamp, &sct_list, &sct_list_len) != 1
|| tls_uint16array_from_bytes(&signature, &signature_len, &sct_list, &sct_list_len) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, entry_ind, "key_id", key_id, 32);
format_print(fp, fmt, entry_ind, "timestamp: %"PRIu64"\n", timestamp);
format_bytes(fp, fmt, entry_ind, "signature", signature, signature_len);
if (dlen) {
error_print();
return -1;
}
}
return 1;
}
// 这个应该改为enable, 服务器也可以设定是否响应这个请求
int tls_enable_signed_certificate_timestamp(TLS_CONNECT *conn)
{
if (!conn) {
error_print();
return -1;
}
conn->signed_certificate_timestamp = 1;
return 1;
}
int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx)
{
if (!ctx) {
error_print();
return -1;
}
ctx->signed_certificate_timestamp = 1;
return 1;
}

163
src/tls_sni.c Normal file
View File

@@ -0,0 +1,163 @@
/*
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <gmssl/rand.h>
#include <gmssl/x509.h>
#include <gmssl/error.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/sm4.h>
#include <gmssl/pem.h>
#include <gmssl/mem.h>
#include <gmssl/tls.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/select.h>
/*
server_name (SNI)
ClientHello.server_name
ext_data = ServerName server_name_list<1..2^16-1>
struct {
uint8 name_type = host_name(0);
opaque host_name<1..2^16-1>;
} ServerName;
ServerHello.server_name
ext_data = empty
*/
int tls_server_name_ext_to_bytes(const uint8_t *host_name, size_t host_name_len, uint8_t **out, size_t *outlen)
{
int type = TLS_extension_server_name;
uint8_t *ext_data = NULL;
size_t ext_datalen = 0;
uint8_t *server_name_list = NULL;
size_t server_name_list_len = 0;
if (out && *out) {
ext_data = *out + 4; // sizeof(ext_header) == 4
server_name_list = ext_data + 2; // sizeof(host_name_list_len) == 2
}
// output one host_name to server_name_list
tls_uint8_to_bytes(TLS_name_type_host_name, &server_name_list, &server_name_list_len);
tls_uint16array_to_bytes(host_name, host_name_len, &server_name_list, &server_name_list_len);
// output ext data
tls_uint16array_to_bytes(NULL, server_name_list_len, &ext_data, &ext_datalen);
// output ext header
tls_ext_to_bytes(type, NULL, ext_datalen, out, outlen);
return 1;
}
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)
{
const uint8_t *server_name_list;
size_t server_name_list_len;
if (!host_name || !host_name_len) {
error_print();
return -1;
}
if (tls_uint16array_from_bytes(&server_name_list, &server_name_list_len, &ext_data, &ext_datalen) != 1
|| tls_length_is_zero(ext_datalen) != 1) {
error_print();
return -1;
}
if (!server_name_list) {
error_print();
return -1;
}
while (server_name_list_len) {
uint8_t name_type;
const uint8_t *name;
size_t namelen;
if (tls_uint8_from_bytes(&name_type, &server_name_list, &server_name_list_len) != 1
|| tls_uint16array_from_bytes(&name, &namelen, &server_name_list, &server_name_list_len) != 1) {
error_print();
return -1;
}
if (name_type != TLS_name_type_host_name) {
error_print();
return -1;
}
if (!name) {
error_print();
return -1;
}
// only return the first hostname
if (*host_name == NULL) {
*host_name = name;
*host_name_len = namelen;
}
}
return 1;
}
int tls_server_name_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
{
const uint8_t *server_name_list;
size_t server_name_list_len;
uint8_t name_type;
const uint8_t *host_name;
size_t host_name_len;
if (tls_uint16array_from_bytes(&server_name_list, &server_name_list_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
while (server_name_list_len) {
if (tls_uint8_from_bytes(&name_type, &server_name_list, &server_name_list_len) != 1
|| tls_uint16array_from_bytes(&host_name, &host_name_len, &server_name_list, &server_name_list_len) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "name_type: %s (%d)\n", name_type == 0 ? "host_name" : "(unknown)", name_type);
format_bytes(fp, fmt, ind, "host_name", host_name, host_name_len); // TODO: print string
}
if (ext_datalen) {
error_print();
return -1;
}
return 1;
}
int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host_name_len)
{
if (!conn || !host_name || !host_name_len) {
error_print();
return -1;
}
if (!conn->is_client) {
error_print();
return -1;
}
if (host_name_len >= sizeof(conn->host_name)) {
error_print();
return -1;
}
memcpy(conn->host_name, host_name, host_name_len);
conn->host_name[host_name_len] = 0;
conn->host_name_len = host_name_len;
conn->server_name = 1;
return 1;
}

View File

@@ -376,6 +376,16 @@ int tls_signature_scheme_from_name(const char *name)
return 0;
}
int tls_signature_scheme_from_algorithm_and_group_oid(int alg_oid, int group_oid)
{
if (alg_oid == OID_sm2sign_with_sm3 && group_oid == OID_sm2) {
return TLS_sig_sm2sig_sm3;
} else if (alg_oid == OID_ecdsa_with_sha256 && group_oid == OID_secp256r1) {
return TLS_sig_ecdsa_secp256r1_sha256;
}
return 0;
}
int tls_signature_scheme_algorithm_oid(int sig_alg)
{
switch (sig_alg) {
@@ -394,26 +404,6 @@ int tls_signature_scheme_group_oid(int sig_alg)
return 0;
}
// 这个函数去掉
int tls_signature_scheme_oid(int sig_alg)
{
switch (sig_alg) {
case TLS_sig_sm2sig_sm3: return OID_sm2sign_with_sm3;
case TLS_sig_ecdsa_secp256r1_sha256: return OID_ecdsa_with_sha256;
}
return 0;
}
// 这个函数也应该修改,必须同时提供算法/group
int tls_signature_scheme_from_oid(int sig_alg_oid)
{
switch (sig_alg_oid) {
case OID_sm2sign_with_sm3: return TLS_sig_sm2sig_sm3;
case OID_ecdsa_with_sha256: return TLS_sig_ecdsa_secp256r1_sha256;
}
return 0;
}
int tls_random_print(FILE *fp, const uint8_t random[32], int format, int indent)
{
time_t gmt_unix_time = 0;

View File

@@ -370,12 +370,28 @@ bad:
}
if (sess_in) {
FILE *sess_infp;
int enable_psk = 0;
int psk_ret = 1;
if (tls13_add_pre_shared_key_from_file(&conn, sess_in) != 1) {
if (!(sess_infp = fopen(sess_in, "rb"))) {
error_print();
return -1;
goto end;
}
tls13_enable_pre_shared_key(&conn, 1);
while (psk_ret) {
if ((psk_ret = tls13_add_pre_shared_key_from_session_file(&conn, sess_infp)) < 0) {
error_print();
fclose(sess_infp);
return -1;
}
}
fclose(sess_infp);
// 客户端是否发送pre_shared_key是由什么决定的需要显式的支持吗
// 我觉得应该是不需要的因为如果设置了psk_key_exchange_mode那么自然要发送pre_shared_key
tls13_enable_pre_shared_key(&conn, enable_psk);
}
if (sess_out) {
@@ -462,10 +478,34 @@ bad:
goto end;
}
fprintf(stderr, ">>>>>>>>>>>>\n");
for (;;) {
fd_set fds;
size_t sentlen;
FD_ZERO(&fds);
// listen socket
FD_SET(conn.sock, &fds);
// listen stdin
FD_SET(fileno(stdin), &fds);
// 等待阻塞
if (select((int)(conn.sock + 1), // In WinSock2, select() ignore the this arg
&fds, NULL, NULL, NULL) < 0) {
fprintf(stderr, "%s: select failed\n", prog);
goto end;
}
/*
if (!fgets(send_buf, sizeof(send_buf), stdin)) {
if (feof(stdin)) {
tls_shutdown(&conn);
@@ -478,21 +518,9 @@ bad:
fprintf(stderr, "%s: send error\n", prog);
goto end;
}
*/
FD_ZERO(&fds);
FD_SET(conn.sock, &fds);
#ifdef WIN32
#else
FD_SET(fileno(stdin), &fds);
#endif
if (select((int)(conn.sock + 1), // In WinSock2, select() ignore the this arg
&fds, NULL, NULL, NULL) < 0) {
fprintf(stderr, "%s: select failed\n", prog);
goto end;
}
if (FD_ISSET(conn.sock, &fds)) {
for (;;) {
memset(buf, 0, sizeof(buf));
@@ -507,10 +535,8 @@ bad:
break;
}
}
}
#ifdef WIN32
#else
if (FD_ISSET(fileno(stdin), &fds)) {
memset(send_buf, 0, sizeof(send_buf));
@@ -527,7 +553,6 @@ bad:
goto end;
}
}
#endif
}
end:

View File

@@ -80,19 +80,28 @@ static const char *help =
" 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"
"\n"
" sudo gmssl tls13_server -port 4430 -cert certs.pem -key signkey.pem -pass 1234 \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"
"\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"
" gmssl tls13_cliet -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\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"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -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 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data\n"
" gmssl tls13_cliet -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data early_data.txt\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 -early_data\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data early_data.txt\n"
"\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 -new_session_ticket 2\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 -new_session_ticket 2\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_dhe_ke -supported_group sm2p256v1 -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_dhe_ke -supported_group sm2p256v1 -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data early_data.txt\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -supported_group sm2p256v1 -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -new_session_ticket 2 -ticket_key $TICKET_KEY\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_dhe_ke -supported_group sm2p256v1 -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -sess_out session.bin\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -ticket_key $TICKET_KEY\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -sess_in session.bin\n"
"\n";
int tls13_server_main(int argc , char **argv)
@@ -342,7 +351,7 @@ bad:
error_print();
return -1;
}
if (tls13_ctx_set_new_session_ticket(&ctx, new_session_ticket) != 1) {
if (tls13_ctx_enable_new_session_ticket(&ctx, new_session_ticket) != 1) {
error_print();
return -1;
}