mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 08:56:17 +08:00
Update TLS 1.3
This commit is contained in:
57
src/tls.c
57
src/tls.c
@@ -1455,6 +1455,56 @@ int tls_cipher_suite_in_list(int cipher, const int *list, size_t list_count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const int tlcp_ciphers[] = {
|
||||
TLS_cipher_ecc_sm4_cbc_sm3,
|
||||
TLS_cipher_ecc_sm4_gcm_sm3,
|
||||
TLS_cipher_ibc_sm4_cbc_sm3,
|
||||
TLS_cipher_ibc_sm4_gcm_sm3,
|
||||
};
|
||||
|
||||
static const int tls12_ciphers[] = {
|
||||
TLS_cipher_ecdhe_sm4_cbc_sm3,
|
||||
TLS_cipher_ecdhe_sm4_gcm_sm3,
|
||||
TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256,
|
||||
};
|
||||
|
||||
static const int tls13_ciphers[] = {
|
||||
TLS_cipher_sm4_gcm_sm3,
|
||||
};
|
||||
|
||||
int tls_cipher_suite_support_protocol(int cipher, int protocol)
|
||||
{
|
||||
const int *ciphers;
|
||||
size_t ciphers_cnt;
|
||||
|
||||
|
||||
switch (protocol) {
|
||||
case TLS_protocol_tlcp:
|
||||
ciphers = tlcp_ciphers;
|
||||
ciphers_cnt = sizeof(tlcp_ciphers)/sizeof(tlcp_ciphers[0]);
|
||||
break;
|
||||
case TLS_protocol_tls12:
|
||||
ciphers = tls12_ciphers;
|
||||
ciphers_cnt = sizeof(tls12_ciphers)/sizeof(tls12_ciphers[0]);
|
||||
break;
|
||||
case TLS_protocol_tls13:
|
||||
ciphers = tls13_ciphers;
|
||||
ciphers_cnt = sizeof(tls13_ciphers)/sizeof(tls13_ciphers[0]);
|
||||
break;
|
||||
default:
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!tls_cipher_suite_in_list(cipher, ciphers, ciphers_cnt)) {
|
||||
error_print();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
尽可能的发送数据,直到发送完整的报文,或者send 返回错误
|
||||
如果send 返回EAGAIN,那么向上层返回WANT_WRITE
|
||||
@@ -2096,8 +2146,6 @@ int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: 根据protocol,核对输入的ciphers是否满足protocol的条件
|
||||
int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt)
|
||||
{
|
||||
size_t i;
|
||||
@@ -2110,6 +2158,7 @@ int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cip
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < cipher_suites_cnt; i++) {
|
||||
if (!tls_cipher_suite_name(cipher_suites[i])) {
|
||||
error_print();
|
||||
@@ -2117,6 +2166,10 @@ int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cip
|
||||
}
|
||||
}
|
||||
for (i = 0; i < cipher_suites_cnt; i++) {
|
||||
if (!tls_cipher_suite_support_protocol(cipher_suites[i], ctx->protocol)) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
ctx->cipher_suites[i] = cipher_suites[i];
|
||||
}
|
||||
ctx->cipher_suites_cnt = cipher_suites_cnt;
|
||||
|
||||
12
src/tls12.c
12
src/tls12.c
@@ -27,11 +27,6 @@
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
static const int tls12_ciphers[] = {
|
||||
TLS_cipher_ecdhe_sm4_cbc_sm3,
|
||||
TLS_cipher_ecdhe_sm4_gcm_sm3,
|
||||
TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256,
|
||||
};
|
||||
|
||||
|
||||
// 现在client_certificate_verify做的是不好的
|
||||
@@ -60,13 +55,18 @@ static const int tls12_ciphers[] = {
|
||||
*/
|
||||
|
||||
// 实际上这个功能本质上是把缓冲区的数据发出去
|
||||
static const int tls12_ciphers[] = {
|
||||
TLS_cipher_ecdhe_sm4_cbc_sm3,
|
||||
TLS_cipher_ecdhe_sm4_gcm_sm3,
|
||||
TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256,
|
||||
};
|
||||
|
||||
|
||||
int tls12_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent)
|
||||
{
|
||||
// 目前只支持TLCP的ECC公钥加密套件,因此不论用哪个套件解析都是一样的
|
||||
// 如果未来支持ECDHE套件,可以将函数改为宏,直接传入 (conn->cipher_suite << 8)
|
||||
format |= tls12_ciphers[0] << 8;
|
||||
format |= tls12_ciphers[0] << 8; // 应该是KeyExchange需要这个参数
|
||||
return tls_record_print(fp, record, recordlen, format, indent);
|
||||
}
|
||||
|
||||
|
||||
31
src/tls13.c
31
src/tls13.c
@@ -640,7 +640,7 @@ int tls13_client_hello_exts_set(uint8_t *exts, size_t *extslen, size_t maxlen,
|
||||
}
|
||||
|
||||
int tls13_process_client_hello_exts(const uint8_t *exts, size_t extslen,
|
||||
const SM2_KEY *server_ecdhe_key, SM2_Z256_POINT *client_ecdhe_public,
|
||||
const SM2_KEY *server_ecdhe_key, SM2_KEY *client_ecdhe_public,
|
||||
uint8_t *server_exts, size_t *server_exts_len, size_t server_exts_maxlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
@@ -735,7 +735,7 @@ int tls_client_key_shares_from_bytes(SM2_Z256_POINT *sm2_point, const uint8_t **
|
||||
}
|
||||
|
||||
// FIXME: should be a process function
|
||||
int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_Z256_POINT *sm2_point)
|
||||
int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_KEY *sm2_key)
|
||||
{
|
||||
uint16_t version;
|
||||
while (extslen) {
|
||||
@@ -759,7 +759,8 @@ int tls13_server_hello_extensions_get(const uint8_t *exts, size_t extslen, SM2_Z
|
||||
}
|
||||
break;
|
||||
case TLS_extension_key_share:
|
||||
if (tls13_process_server_key_share(ext_data, ext_datalen, sm2_point) != 1) {
|
||||
memset(sm2_key, 0, sizeof(SM2_KEY));
|
||||
if (tls13_process_server_key_share(ext_data, ext_datalen, &sm2_key->public_key) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -1502,7 +1503,7 @@ int tls13_do_connect(TLS_CONNECT *conn)
|
||||
size_t server_verify_data_len;
|
||||
|
||||
SM2_KEY client_ecdhe;
|
||||
SM2_Z256_POINT server_ecdhe_public;
|
||||
SM2_KEY server_ecdhe_public;
|
||||
X509_KEY server_sign_key;
|
||||
|
||||
const DIGEST *digest = DIGEST_sm3();
|
||||
@@ -1589,7 +1590,7 @@ int tls13_do_connect(TLS_CONNECT *conn)
|
||||
goto end;
|
||||
}
|
||||
conn->cipher_suite = cipher_suite;
|
||||
if (tls13_server_hello_extensions_get(server_exts, server_exts_len, &server_ecdhe_public) != 1) {
|
||||
if (tls13_server_hello_extensions_get(server_exts, server_exts_len, &server_ecdhe_public) != 1) {
|
||||
error_print();
|
||||
tls_send_alert(conn, TLS_alert_handshake_failure);
|
||||
goto end;
|
||||
@@ -1609,12 +1610,11 @@ int tls13_do_connect(TLS_CONNECT *conn)
|
||||
uint8_t client_write_iv[12]
|
||||
uint8_t server_write_iv[12]
|
||||
*/
|
||||
sm2_do_ecdh(&client_ecdhe, &server_ecdhe_public, &server_ecdhe_public);
|
||||
uint8_t share_point[64];
|
||||
sm2_z256_point_to_bytes(&server_ecdhe_public, share_point);
|
||||
uint8_t share_point_x[32];
|
||||
sm2_do_ecdh(&client_ecdhe, &server_ecdhe_public, share_point_x);
|
||||
/* [1] */ tls13_hkdf_extract(digest, zeros, psk, early_secret);
|
||||
/* [5] */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret);
|
||||
/* [6] */ tls13_hkdf_extract(digest, handshake_secret, share_point, handshake_secret);
|
||||
/* [6] */ tls13_hkdf_extract(digest, handshake_secret, share_point_x, handshake_secret);
|
||||
/* [7] */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret);
|
||||
/* [8] */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret);
|
||||
/* [9] */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret);
|
||||
@@ -1864,7 +1864,7 @@ int tls13_do_connect(TLS_CONNECT *conn)
|
||||
// send {CertificateVerify*}
|
||||
tls_trace("send {CertificateVerify*}\n");
|
||||
client_sign_algor = TLS_sig_sm2sig_sm3; // FIXME: 应该放在conn里面
|
||||
tls13_sign_certificate_verify(TLS_client_mode, &conn->sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen);
|
||||
tls13_sign_certificate_verify(TLS_client_mode, &conn->sign_key.u.sm2_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen);
|
||||
if (tls13_record_set_handshake_certificate_verify(record, &recordlen,
|
||||
client_sign_algor, sig, siglen) != 1) {
|
||||
error_print();
|
||||
@@ -1986,7 +1986,7 @@ int tls13_do_accept(TLS_CONNECT *conn)
|
||||
size_t server_exts_len;
|
||||
|
||||
SM2_KEY server_ecdhe;
|
||||
SM2_Z256_POINT client_ecdhe_public;
|
||||
SM2_KEY client_ecdhe_public;
|
||||
X509_KEY client_sign_key;
|
||||
const BLOCK_CIPHER *cipher = NULL;
|
||||
const DIGEST *digest = NULL;
|
||||
@@ -2098,13 +2098,12 @@ int tls13_do_accept(TLS_CONNECT *conn)
|
||||
digest_update(&dgst_ctx, record + 5, recordlen - 5);
|
||||
|
||||
|
||||
sm2_do_ecdh(&server_ecdhe, &client_ecdhe_public, &client_ecdhe_public);
|
||||
uint8_t share_point[64];//FIXME: 应该重新考虑TLS中如何使用sm2_do_ecdh还是sm2_ecdh
|
||||
sm2_z256_point_to_bytes(&client_ecdhe_public, share_point);
|
||||
uint8_t share_point_x[32];
|
||||
sm2_do_ecdh(&server_ecdhe, &client_ecdhe_public, share_point_x);
|
||||
|
||||
/* 1 */ tls13_hkdf_extract(digest, zeros, psk, early_secret);
|
||||
/* 5 */ tls13_derive_secret(early_secret, "derived", &null_dgst_ctx, handshake_secret);
|
||||
/* 6 */ tls13_hkdf_extract(digest, handshake_secret, share_point, handshake_secret);
|
||||
/* 6 */ tls13_hkdf_extract(digest, handshake_secret, share_point_x, handshake_secret);
|
||||
/* 7 */ tls13_derive_secret(handshake_secret, "c hs traffic", &dgst_ctx, client_handshake_traffic_secret);
|
||||
/* 8 */ tls13_derive_secret(handshake_secret, "s hs traffic", &dgst_ctx, server_handshake_traffic_secret);
|
||||
/* 9 */ tls13_derive_secret(handshake_secret, "derived", &null_dgst_ctx, master_secret);
|
||||
@@ -2204,7 +2203,7 @@ int tls13_do_accept(TLS_CONNECT *conn)
|
||||
|
||||
// send Server {CertificateVerify}
|
||||
tls_trace("send {CertificateVerify}\n");
|
||||
tls13_sign_certificate_verify(TLS_server_mode, &conn->sign_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen);
|
||||
tls13_sign_certificate_verify(TLS_server_mode, &conn->sign_key.u.sm2_key, TLS13_SM2_ID, TLS13_SM2_ID_LENGTH, &dgst_ctx, sig, &siglen);
|
||||
if (tls13_record_set_handshake_certificate_verify(record, &recordlen,
|
||||
TLS_sig_sm2sig_sm3, sig, siglen) != 1) {
|
||||
error_print();
|
||||
|
||||
@@ -706,7 +706,7 @@ int tls13_client_key_share_ext_to_bytes(const SM2_Z256_POINT *point, uint8_t **o
|
||||
}
|
||||
|
||||
int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen,
|
||||
const SM2_KEY *server_ecdhe_key, SM2_Z256_POINT *client_ecdhe_public,
|
||||
const SM2_KEY *server_ecdhe_key, SM2_KEY *client_ecdhe_public,
|
||||
uint8_t **out, size_t *outlen)
|
||||
{
|
||||
const uint8_t *client_shares;
|
||||
@@ -743,7 +743,8 @@ int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen,
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_z256_point_from_octets(client_ecdhe_public, key_exchange, key_exchange_len) != 1) {
|
||||
memset(client_ecdhe_public, 0, sizeof(SM2_KEY));
|
||||
if (sm2_z256_point_from_octets(&client_ecdhe_public->public_key, key_exchange, key_exchange_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -707,6 +707,12 @@ int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t da
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// 这个函数依赖输入的cipher_suite,才能判断如何解析ServerKeyExchange
|
||||
// 显然这个信息无法通过基础的format提供了,并且这个底层的信息一直需要从最上层提供,这就非常不好了
|
||||
// 目前来看,cipher_suite是否能够提供足够的信息呢?
|
||||
// ServerKeyExchange, ClientKeyExchange的格式是由cipher_suite决定的
|
||||
|
||||
int tls_server_key_exchange_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent)
|
||||
{
|
||||
int cipher_suite = (format >> 8) & 0xffff;
|
||||
@@ -1072,8 +1078,6 @@ int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record,
|
||||
|
||||
// FIXME: 根据RFC来考虑这个函数的参数,从底向上逐步修改每个函数的接口参数
|
||||
|
||||
// 仅从record数据是不能判断这个record是TLS 1.2还是TLS 1.3
|
||||
// 不同协议上,同名的握手消息,其格式也是不一样的。这真是太恶心了!!!!
|
||||
|
||||
// 当消息为ClientKeyExchange,ServerKeyExchange,需要密码套件中的密钥交换算法信息
|
||||
// 当消息为加密的Finished,记录类型为Handshake,但是记录负载数据中没有Handshake头
|
||||
@@ -1081,6 +1085,13 @@ int tls13_record_print(FILE *fp, int format, int indent, const uint8_t *record,
|
||||
//
|
||||
// supported_versions 的格式由handshake_type 是否为ClientHello, ServerHello 决定
|
||||
// record中是包含这个信息的,但是在exts中没有这个信息
|
||||
|
||||
int tls_print_record(FILE *fp, int fmt, int ind, const char *label, TLS_CONNECT *conn)
|
||||
{
|
||||
tls_record_print(fp, conn->record, conn->recordlen, fmt, ind);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent)
|
||||
{
|
||||
const uint8_t *data;
|
||||
|
||||
Reference in New Issue
Block a user