mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-19 19:33:38 +08:00
Clean TLS code
This commit is contained in:
@@ -818,7 +818,7 @@ endif()
|
|||||||
#
|
#
|
||||||
set(CPACK_PACKAGE_NAME "GmSSL")
|
set(CPACK_PACKAGE_NAME "GmSSL")
|
||||||
set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
|
set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
|
||||||
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1059")
|
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1060")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
|
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
|
||||||
set(CPACK_NSIS_MODIFY_PATH ON)
|
set(CPACK_NSIS_MODIFY_PATH ON)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|||||||
@@ -1188,11 +1188,13 @@ typedef struct {
|
|||||||
BLOCK_CIPHER_KEY client_write_key;
|
BLOCK_CIPHER_KEY client_write_key;
|
||||||
BLOCK_CIPHER_KEY server_write_key;
|
BLOCK_CIPHER_KEY server_write_key;
|
||||||
|
|
||||||
uint8_t pre_master_secret[48]; // 是否可以重用master_secret作为pre_master_secret呢?
|
uint8_t pre_master_secret[48];
|
||||||
|
size_t pre_master_secret_len;
|
||||||
uint8_t master_secret[48];
|
uint8_t master_secret[48];
|
||||||
uint8_t resumption_master_secret[48];
|
uint8_t resumption_master_secret[48];
|
||||||
|
|
||||||
uint8_t key_block[96];
|
uint8_t key_block[96];
|
||||||
|
size_t key_block_len;
|
||||||
|
|
||||||
|
|
||||||
uint8_t early_secret[32];
|
uint8_t early_secret[32];
|
||||||
@@ -1214,6 +1216,9 @@ typedef struct {
|
|||||||
|
|
||||||
// CertificateRequest
|
// CertificateRequest
|
||||||
int certificate_request;
|
int certificate_request;
|
||||||
|
uint8_t transcript[TLS_MAX_RECORD_SIZE * 2];
|
||||||
|
size_t transcript_len;
|
||||||
|
|
||||||
|
|
||||||
// NewSessionTicket
|
// NewSessionTicket
|
||||||
int new_session_ticket;
|
int new_session_ticket;
|
||||||
@@ -1493,14 +1498,22 @@ int tls13_ctx_set_change_cipher_spec_compat(TLS_CTX *ctx, int enable);
|
|||||||
int tls13_ctx_set_accept_change_cipher_spec(TLS_CTX *ctx, int enable);
|
int tls13_ctx_set_accept_change_cipher_spec(TLS_CTX *ctx, int enable);
|
||||||
int tls13_ctx_enable_change_cipher_spec(TLS_CTX *ctx, int enable);
|
int tls13_ctx_enable_change_cipher_spec(TLS_CTX *ctx, int enable);
|
||||||
|
|
||||||
|
int tlcp_generate_pre_master_secret(TLS_CONNECT *conn);
|
||||||
|
int tlcp_check_pre_master_secret(TLS_CONNECT *conn);
|
||||||
|
|
||||||
|
int tls_derive_pre_master_secret(TLS_CONNECT *conn);
|
||||||
|
int tls_derive_master_secret(TLS_CONNECT *conn);
|
||||||
|
int tls_derive_key_block(TLS_CONNECT *conn);
|
||||||
|
int tls_init_application_keys(TLS_CONNECT *conn);
|
||||||
|
|
||||||
int tls_generate_keys(TLS_CONNECT *conn);
|
|
||||||
|
|
||||||
int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48],
|
int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48],
|
||||||
const char *label, const DIGEST_CTX *dgst_ctx, uint8_t verify_data[12]);
|
const char *label, const DIGEST_CTX *dgst_ctx, uint8_t verify_data[12]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int tls13_update_client_application_keys(TLS_CONNECT *conn);
|
int tls13_update_client_application_keys(TLS_CONNECT *conn);
|
||||||
int tls13_update_server_application_keys(TLS_CONNECT *conn);
|
int tls13_update_server_application_keys(TLS_CONNECT *conn);
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
#define GMSSL_VERSION_NUM 30200
|
#define GMSSL_VERSION_NUM 30200
|
||||||
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1059"
|
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1060"
|
||||||
|
|
||||||
int gmssl_version_num(void);
|
int gmssl_version_num(void);
|
||||||
const char *gmssl_version_str(void);
|
const char *gmssl_version_str(void);
|
||||||
|
|||||||
589
src/tlcp.c
589
src/tlcp.c
@@ -24,6 +24,40 @@
|
|||||||
#include <gmssl/tls.h>
|
#include <gmssl/tls.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
TLCP只支持SM3,这使得transcript-hash的计算更简单
|
||||||
|
|
||||||
|
对于服务器来说,ServerKeyExchange中的签名并不是对transcript-hash做的
|
||||||
|
而是对random, server_cert做的,并且服务器知道自己的ID和公钥,
|
||||||
|
因此都可以在send_server_key_exchange中完成
|
||||||
|
|
||||||
|
但是如果要做CertificateVerify
|
||||||
|
被签名的消息:
|
||||||
|
|
||||||
|
ClientHello
|
||||||
|
ServerHello
|
||||||
|
server Certificate
|
||||||
|
ServerKeyExchange
|
||||||
|
CertificateRequest
|
||||||
|
ServerHelloDone
|
||||||
|
client Certificate
|
||||||
|
ClientKeyExchange
|
||||||
|
|
||||||
|
服务器只有在接收到client Certificate的时候才知道客户端的公钥,才能启动签名验证
|
||||||
|
因此对于服务器来说,必须备份所有的消息。
|
||||||
|
|
||||||
|
|
||||||
|
支持SNI的时候,客户端可能有多个签名私钥。
|
||||||
|
为了简便起见,我们缓冲所有的消息,直到ClientKeyExchange
|
||||||
|
客户端在这个时候启动签名
|
||||||
|
|
||||||
|
服务器端也可以在这个时候验证签名
|
||||||
|
|
||||||
|
这是最简单的,而且对于TLCP, TLS12都是一样的
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const int tlcp_supported_groups[] = {
|
const int tlcp_supported_groups[] = {
|
||||||
TLS_curve_sm2p256v1,
|
TLS_curve_sm2p256v1,
|
||||||
};
|
};
|
||||||
@@ -50,79 +84,6 @@ int tlcp_record_print(FILE *fp, int fmt, int ind, const uint8_t *record, size_t
|
|||||||
record, recordlen);
|
record, recordlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tlcp_record_encrypt(int cipher_suite,
|
|
||||||
const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
|
||||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
|
||||||
uint8_t *out, size_t *outlen)
|
|
||||||
{
|
|
||||||
switch (cipher_suite) {
|
|
||||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
|
||||||
if (tls_cbc_encrypt(hmac_ctx, key, seq_num, in,
|
|
||||||
in + 5, inlen - 5,
|
|
||||||
out + 5, outlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
|
||||||
if (tls_gcm_encrypt(key, fixed_iv, seq_num, in,
|
|
||||||
in + 5, inlen - 5,
|
|
||||||
out + 5, outlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
out[0] = in[0];
|
|
||||||
out[1] = in[1];
|
|
||||||
out[2] = in[2];
|
|
||||||
out[3] = (uint8_t)((*outlen) >> 8);
|
|
||||||
out[4] = (uint8_t)(*outlen);
|
|
||||||
(*outlen) += 5;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tlcp_record_decrypt(int cipher_suite,
|
|
||||||
const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
|
||||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
|
||||||
uint8_t *out, size_t *outlen)
|
|
||||||
{
|
|
||||||
switch (cipher_suite) {
|
|
||||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
|
||||||
if (tls_cbc_decrypt(hmac_ctx, key, seq_num, in,
|
|
||||||
in + 5, inlen - 5,
|
|
||||||
out + 5, outlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
|
||||||
if (tls_gcm_decrypt(key, fixed_iv, seq_num, in,
|
|
||||||
in + 5, inlen - 5,
|
|
||||||
out + 5, outlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
out[0] = in[0];
|
|
||||||
out[1] = in[1];
|
|
||||||
out[2] = in[2];
|
|
||||||
out[3] = (uint8_t)((*outlen) >> 8);
|
|
||||||
out[4] = (uint8_t)(*outlen);
|
|
||||||
(*outlen) += 5;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ServerKeyExchange
|
ServerKeyExchange
|
||||||
|
|
||||||
@@ -162,7 +123,6 @@ select (KeyExchangeAlgorithm) {
|
|||||||
`signed_params` is DER signature encoded in uint16array
|
`signed_params` is DER signature encoded in uint16array
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int tlcp_server_key_exchange_ecc_print(FILE *fp, const uint8_t *data, size_t datalen, int fmt, int ind)
|
int tlcp_server_key_exchange_ecc_print(FILE *fp, const uint8_t *data, size_t datalen, int fmt, int ind)
|
||||||
{
|
{
|
||||||
const uint8_t *sig;
|
const uint8_t *sig;
|
||||||
@@ -308,9 +268,8 @@ struct {
|
|||||||
opaque RSAEncryptedPreMasterSecret<0..2^16-1>;
|
opaque RSAEncryptedPreMasterSecret<0..2^16-1>;
|
||||||
} exchange_keys;
|
} exchange_keys;
|
||||||
} ClientKeyExchange;
|
} ClientKeyExchange;
|
||||||
|
|
||||||
// 不管算法是什么,数据格式都是uint16array
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int tlcp_record_set_handshake_client_key_exchange(uint8_t *record, size_t *recordlen,
|
int tlcp_record_set_handshake_client_key_exchange(uint8_t *record, size_t *recordlen,
|
||||||
const uint8_t *enced_pms, size_t enced_pms_len)
|
const uint8_t *enced_pms, size_t enced_pms_len)
|
||||||
{
|
{
|
||||||
@@ -356,13 +315,16 @@ int tlcp_record_get_handshake_client_key_exchange(const uint8_t *record,
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (!enced_pms_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct {
|
struct {
|
||||||
ClientCertificateType certificate_types<1..2^8-1>;
|
ClientCertificateType certificate_types<1..2^8-1>;
|
||||||
SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; // TLS 1.2 only
|
|
||||||
DistinguishedName certificate_authorities<0..2^16-1>;
|
DistinguishedName certificate_authorities<0..2^16-1>;
|
||||||
} CertificateRequest;
|
} CertificateRequest;
|
||||||
*/
|
*/
|
||||||
@@ -566,9 +528,8 @@ int tlcp_send_client_hello(TLS_CONNECT *conn)
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (conn->verbose) {
|
if (conn->verbose)
|
||||||
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
||||||
}
|
|
||||||
|
|
||||||
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -625,6 +586,13 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
|
|||||||
if (conn->verbose)
|
if (conn->verbose)
|
||||||
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
||||||
|
|
||||||
|
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (conn->verbose)
|
||||||
|
tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
|
||||||
|
|
||||||
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_protocol_version);
|
tls_send_alert(conn, TLS_alert_protocol_version);
|
||||||
@@ -645,6 +613,8 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
memcpy(conn->server_random, server_random, 32);
|
memcpy(conn->server_random, server_random, 32);
|
||||||
memcpy(conn->session_id, session_id, session_id_len);
|
memcpy(conn->session_id, session_id, session_id_len);
|
||||||
|
conn->session_id_len = session_id_len;
|
||||||
|
|
||||||
if (tls_type_is_in_list(cipher_suite,
|
if (tls_type_is_in_list(cipher_suite,
|
||||||
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt) != 1) {
|
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -793,13 +763,6 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
|
|||||||
conn->application_layer_protocol_negotiation = 1;
|
conn->application_layer_protocol_negotiation = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerHello", &conn->dgst_ctx);
|
|
||||||
|
|
||||||
if (conn->client_certs_len) {
|
if (conn->client_certs_len) {
|
||||||
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
}
|
}
|
||||||
@@ -810,10 +773,9 @@ int tlcp_recv_server_hello(TLS_CONNECT *conn)
|
|||||||
int tlcp_recv_server_certificate(TLS_CONNECT *conn)
|
int tlcp_recv_server_certificate(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int verify_result;
|
|
||||||
const uint8_t *server_cert;
|
const uint8_t *server_cert;
|
||||||
size_t server_cert_len;
|
size_t server_cert_len;
|
||||||
|
int verify_result;
|
||||||
|
|
||||||
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) {
|
||||||
@@ -826,26 +788,16 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn)
|
|||||||
if (conn->verbose)
|
if (conn->verbose)
|
||||||
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
||||||
|
|
||||||
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_protocol_version);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx);
|
if (conn->verbose)
|
||||||
|
tls_handshake_digest_print(stderr, 0, 0, "Certificate", &conn->dgst_ctx);
|
||||||
|
|
||||||
if (conn->client_certs_len) {
|
|
||||||
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_protocol_version);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,7 +807,6 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn)
|
|||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len,
|
if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len,
|
||||||
0, &server_cert, &server_cert_len) != 1) {
|
0, &server_cert, &server_cert_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -874,6 +825,8 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// FIXME: 需要根据密码套件、ClientHello扩展等对证书做进一步的验证
|
||||||
|
// x509_certs_verify_tlcp 只是验证证书链有效,不能完全判定服务器证书有效
|
||||||
|
|
||||||
if (conn->ctx->cacertslen) {
|
if (conn->ctx->cacertslen) {
|
||||||
if (x509_certs_verify_tlcp(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
|
if (x509_certs_verify_tlcp(conn->peer_cert_chain, conn->peer_cert_chain_len, X509_cert_chain_server,
|
||||||
@@ -884,6 +837,10 @@ int tlcp_recv_server_certificate(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conn->client_certs_len) {
|
||||||
|
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,6 +870,13 @@ int tlcp_recv_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
if (conn->verbose)
|
if (conn->verbose)
|
||||||
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
||||||
|
|
||||||
|
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(conn->verbose)
|
||||||
|
tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx);
|
||||||
|
|
||||||
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_protocol_version);
|
tls_send_alert(conn, TLS_alert_protocol_version);
|
||||||
@@ -924,18 +888,11 @@ int tlcp_recv_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(conn->verbose)
|
|
||||||
tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx);
|
|
||||||
|
|
||||||
// verify ServerKeyExchange
|
// verify ServerKeyExchange
|
||||||
if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 0, &sign_cert, &sign_cert_len) != 1
|
if (x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 0, &sign_cert, &sign_cert_len) != 1
|
||||||
|| x509_cert_get_subject_public_key(sign_cert, sign_cert_len, &sign_key) != 1
|
|| x509_cert_get_subject_public_key(sign_cert, sign_cert_len, &sign_key) != 1
|
||||||
|| x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 1, &enc_cert, &enc_cert_len) != 1
|
|| x509_certs_get_cert_by_index(conn->peer_cert_chain, conn->peer_cert_chain_len, 1, &enc_cert, &enc_cert_len) != 1) {
|
||||||
|| x509_cert_get_subject_public_key(enc_cert, enc_cert_len, &conn->server_enc_key) != 1) { // 这个不应该在这里取
|
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1015,7 +972,6 @@ int tlcp_recv_certificate_request(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当采用SM9时有什么特别处理?
|
|
||||||
if (tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) {
|
if (tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_unsupported_certificate);
|
tls_send_alert(conn, TLS_alert_unsupported_certificate);
|
||||||
@@ -1026,8 +982,9 @@ int tlcp_recv_certificate_request(TLS_CONNECT *conn)
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (conn->verbose)
|
||||||
|
tls_handshake_digest_print(stderr, 0, 0, "CertificateRequest", &conn->dgst_ctx);
|
||||||
|
|
||||||
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "CertificateRequest", &conn->dgst_ctx);
|
|
||||||
|
|
||||||
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
|
|
||||||
@@ -1149,7 +1106,10 @@ int tlcp_send_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls_pre_master_secret_generate(conn->pre_master_secret, TLS_protocol_tlcp) != 1) {
|
if (tlcp_generate_pre_master_secret(conn) != 1
|
||||||
|
|| tls_derive_master_secret(conn) != 1
|
||||||
|
|| tls_derive_key_block(conn) != 1
|
||||||
|
|| tls_init_application_keys(conn) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1175,6 +1135,7 @@ int tlcp_send_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
if (conn->verbose)
|
if (conn->verbose)
|
||||||
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
|
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = tls_send_record(conn)) != 1) {
|
if ((ret = tls_send_record(conn)) != 1) {
|
||||||
@@ -1186,23 +1147,10 @@ int tlcp_send_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
|
|
||||||
tls_clean_record(conn);
|
tls_clean_record(conn);
|
||||||
|
|
||||||
if (tlcp_generate_keys(conn) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int tlcp_send_certificate_verify(TLS_CONNECT *conn)
|
int tlcp_send_certificate_verify(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -1251,12 +1199,12 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
|
|||||||
if (conn->recordlen == 0) {
|
if (conn->recordlen == 0) {
|
||||||
uint8_t verify_data[12];
|
uint8_t verify_data[12];
|
||||||
|
|
||||||
if(conn->verbose) tls_trace("send client {Finished}\n");
|
if (conn->verbose)
|
||||||
|
tls_trace("send client {Finished}\n");
|
||||||
|
|
||||||
if (tls_compute_verify_data(conn->digest, conn->master_secret, "client finished", &conn->dgst_ctx, verify_data) != 1) {
|
if (tls_compute_verify_data(conn->digest, conn->master_secret, "client finished", &conn->dgst_ctx, verify_data) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_internal_error);
|
tls12_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1265,7 +1213,7 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
|
|||||||
if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen,
|
if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen,
|
||||||
verify_data, sizeof(verify_data)) != 1) {
|
verify_data, sizeof(verify_data)) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_internal_error);
|
tls12_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1276,19 +1224,17 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "client Finished", &conn->dgst_ctx);
|
if (conn->verbose)
|
||||||
|
tls_handshake_digest_print(stderr, 0, 0, "client Finished", &conn->dgst_ctx);
|
||||||
|
|
||||||
|
if (tls_record_encrypt(conn->cipher_suite,
|
||||||
if (tlcp_record_encrypt(conn->cipher_suite,
|
|
||||||
&conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv,
|
&conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv,
|
||||||
conn->client_seq_num, conn->plain_record, conn->plain_recordlen,
|
conn->client_seq_num, conn->plain_record, conn->plain_recordlen,
|
||||||
conn->record, &conn->recordlen) != 1) {
|
conn->record, &conn->recordlen) != 1) {
|
||||||
|
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_internal_error);
|
tls12_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls_seq_num_incr(conn->client_seq_num);
|
tls_seq_num_incr(conn->client_seq_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1298,8 +1244,6 @@ int tlcp_send_client_finished(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1314,7 +1258,6 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn)
|
|||||||
uint8_t local_verify_data[12];
|
uint8_t local_verify_data[12];
|
||||||
|
|
||||||
|
|
||||||
if(conn->verbose) tls_trace("recv server {Finished}\n");
|
|
||||||
|
|
||||||
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) {
|
||||||
@@ -1322,50 +1265,53 @@ int tlcp_recv_server_finished(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if(conn->verbose)
|
||||||
|
tls_trace("recv server {Finished}\n");
|
||||||
|
|
||||||
if (conn->verbose)
|
if (conn->verbose)
|
||||||
tls_encrypted_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
tls_encrypted_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
||||||
|
|
||||||
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_unexpected_message);
|
tls12_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlcp_record_decrypt(conn->cipher_suite,
|
if (tls_record_decrypt(conn->cipher_suite,
|
||||||
&conn->server_write_mac_ctx, &conn->server_write_key, conn->server_write_iv,
|
&conn->server_write_mac_ctx, &conn->server_write_key, conn->server_write_iv,
|
||||||
conn->server_seq_num, conn->record, conn->recordlen,
|
conn->server_seq_num, conn->record, conn->recordlen,
|
||||||
conn->plain_record, &conn->plain_recordlen) != 1) {
|
conn->plain_record, &conn->plain_recordlen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_bad_record_mac);
|
tls12_send_alert(conn, TLS_alert_bad_record_mac);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tls_seq_num_incr(conn->server_seq_num);
|
tls_seq_num_incr(conn->server_seq_num);
|
||||||
|
|
||||||
if (conn->verbose)
|
if (conn->verbose)
|
||||||
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
|
||||||
|
// no more digest_update
|
||||||
// 最后没有必要再计算handshke_digest了
|
|
||||||
|
|
||||||
if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) {
|
if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_unexpected_message);
|
tls12_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (verify_data_len != sizeof(local_verify_data)) {
|
if (verify_data_len != sizeof(local_verify_data)) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_unexpected_message);
|
tls12_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished", &conn->dgst_ctx, local_verify_data) != 1) {
|
if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished", &conn->dgst_ctx, local_verify_data) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_internal_error);
|
tls12_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
memset(&conn->dgst_ctx, 0, sizeof(conn->dgst_ctx));
|
||||||
|
|
||||||
if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) {
|
if (memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_decrypt_error);
|
tls12_send_alert(conn, TLS_alert_decrypt_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1889,22 +1835,6 @@ int tlcp_send_server_hello(TLS_CONNECT *conn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
-- IBC_SM4_CBC_SM3 和 IBC_SM4_GCM_SM3 套件的服务器Certificate消息格式
|
|
||||||
|
|
||||||
opaque ASN.1IBCParam<1..2^24-1>
|
|
||||||
|
|
||||||
struct {
|
|
||||||
opaque ibc_id<1..2^16-1>;
|
|
||||||
ASN.1IBCParam ibc_parameter;
|
|
||||||
} Certificate;
|
|
||||||
|
|
||||||
其中ibc_id是服务器的SM9的ID,这个ID暂时是一个没有内部结构的字节串,后续有可能是一个DER结构的字节串
|
|
||||||
ibc_parameter 是SM9 sm9_enc_master_key_to_der 输出的DER数据
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
int tlcp_send_server_certificate(TLS_CONNECT *conn)
|
int tlcp_send_server_certificate(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -2026,134 +1956,6 @@ int tlcp_send_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int tlcp_generate_master_secret(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
if (!conn) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_prf(conn->digest, conn->pre_master_secret, 48, "master secret",
|
|
||||||
conn->client_random, 32,
|
|
||||||
conn->server_random, 32,
|
|
||||||
48, conn->master_secret) != 1) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tlcp_generate_key_block(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
size_t key_block_len;
|
|
||||||
|
|
||||||
if (!conn) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
switch (conn->cipher_suite) {
|
|
||||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
|
||||||
if (!conn->cipher) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
key_block_len = conn->cipher->key_size * 2 + 8;
|
|
||||||
break;
|
|
||||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
|
||||||
key_block_len = 96;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_prf(conn->digest, conn->master_secret, 48, "key expansion",
|
|
||||||
conn->server_random, 32,
|
|
||||||
conn->client_random, 32,
|
|
||||||
key_block_len, conn->key_block) != 1) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tlcp_generate_record_keys(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
if (!conn) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
switch (conn->cipher_suite) {
|
|
||||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
|
||||||
{
|
|
||||||
size_t keylen;
|
|
||||||
|
|
||||||
if (!conn->cipher) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
keylen = conn->cipher->key_size;
|
|
||||||
|
|
||||||
memset(conn->client_write_iv, 0, sizeof(conn->client_write_iv));
|
|
||||||
memset(conn->server_write_iv, 0, sizeof(conn->server_write_iv));
|
|
||||||
memcpy(conn->client_write_iv, conn->key_block + keylen * 2, 4);
|
|
||||||
memcpy(conn->server_write_iv, conn->key_block + keylen * 2 + 4, 4);
|
|
||||||
|
|
||||||
if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block) != 1
|
|
||||||
|| block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + keylen) != 1) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
|
||||||
if (hmac_init(&conn->client_write_mac_ctx, conn->digest, conn->key_block, 32) != 1
|
|
||||||
|| hmac_init(&conn->server_write_mac_ctx, conn->digest, conn->key_block + 32, 32) != 1) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->is_client) {
|
|
||||||
if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1
|
|
||||||
|| block_cipher_set_decrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (block_cipher_set_decrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1
|
|
||||||
|| block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tlcp_secrets_print(TLS_CONNECT *conn)
|
static void tlcp_secrets_print(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
if (conn->verbose < 5) {
|
if (conn->verbose < 5) {
|
||||||
@@ -2181,25 +1983,47 @@ static void tlcp_secrets_print(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int tlcp_generate_keys(TLS_CONNECT *conn)
|
int tlcp_generate_pre_master_secret(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
if(conn->verbose) tls_trace("generate secrets\n");
|
uint8_t *pre_master_secret;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
if (tlcp_generate_master_secret(conn) != 1
|
if (!conn || conn->protocol != TLS_protocol_tlcp) {
|
||||||
|| tlcp_generate_key_block(conn) != 1
|
|
||||||
|| tlcp_generate_record_keys(conn) != 1) {
|
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tls_seq_num_reset(conn->client_seq_num);
|
pre_master_secret = conn->pre_master_secret;
|
||||||
tls_seq_num_reset(conn->server_seq_num);
|
tls_uint16_to_bytes((uint16_t)conn->protocol, &pre_master_secret, &len);
|
||||||
|
if (rand_bytes(pre_master_secret, 46) != 1) {
|
||||||
tlcp_secrets_print(conn);
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
conn->pre_master_secret_len = 48;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tlcp_check_pre_master_secret(TLS_CONNECT *conn)
|
||||||
|
{
|
||||||
|
const uint8_t *pre_master_secret;
|
||||||
|
size_t len = 2;
|
||||||
|
uint16_t protocol;
|
||||||
|
|
||||||
|
if (!conn || conn->protocol != TLS_protocol_tlcp
|
||||||
|
|| conn->pre_master_secret_len != 48) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
pre_master_secret = conn->pre_master_secret;
|
||||||
|
if (tls_uint16_from_bytes(&protocol, &pre_master_secret, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (protocol != conn->protocol) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int tlcp_send_certificate_request(TLS_CONNECT *conn)
|
int tlcp_send_certificate_request(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
@@ -2259,13 +2083,10 @@ int tlcp_recv_client_certificate(TLS_CONNECT *conn)
|
|||||||
|
|
||||||
int tlcp_recv_client_key_exchange(TLS_CONNECT *conn)
|
int tlcp_recv_client_key_exchange(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
const uint8_t *enced_pms;
|
const uint8_t *enced_pms;
|
||||||
size_t enced_pms_len;
|
size_t enced_pms_len;
|
||||||
size_t pre_master_secret_len;
|
|
||||||
X509_KEY *enc_key;
|
X509_KEY *enc_key;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if(conn->verbose) tls_trace("recv ClientKeyExchange\n");
|
|
||||||
|
|
||||||
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) {
|
||||||
@@ -2273,6 +2094,8 @@ int tlcp_recv_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if (conn->verbose)
|
||||||
|
tls_trace("recv ClientKeyExchange\n");
|
||||||
|
|
||||||
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
if (tls_record_protocol(conn->record) != TLS_protocol_tlcp) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -2282,11 +2105,24 @@ int tlcp_recv_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
if (conn->verbose)
|
if (conn->verbose)
|
||||||
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
||||||
|
|
||||||
if (tlcp_record_get_handshake_client_key_exchange(conn->record, &enced_pms, &enced_pms_len) != 1) {
|
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (conn->verbose)
|
||||||
|
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
|
||||||
|
|
||||||
|
if ((ret = tlcp_record_get_handshake_client_key_exchange(conn->record, &enced_pms, &enced_pms_len)) < 0) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_decode_error);
|
||||||
|
return -1;
|
||||||
|
} else if (ret == 0) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// decrypt enced_pre_master_secret
|
||||||
if (!conn->cert_chain_idx) {
|
if (!conn->cert_chain_idx) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
@@ -2298,34 +2134,20 @@ int tlcp_recv_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME:
|
|
||||||
// 这里需要检查一下密钥的长度,因为输入的长度是确定的,因此输出的密文长度应该也是确定的
|
|
||||||
|
|
||||||
if (sm2_decrypt(&enc_key->u.sm2_key, enced_pms, enced_pms_len,
|
if (sm2_decrypt(&enc_key->u.sm2_key, enced_pms, enced_pms_len,
|
||||||
conn->pre_master_secret, &pre_master_secret_len) != 1) {
|
conn->pre_master_secret, &conn->pre_master_secret_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_decrypt_error);
|
tls_send_alert(conn, TLS_alert_decrypt_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (pre_master_secret_len != 48) {
|
if (tlcp_check_pre_master_secret(conn) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_decrypt_error);
|
tls_send_alert(conn, TLS_alert_illegal_parameter);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((((uint16_t)conn->pre_master_secret[0] << 8) | conn->pre_master_secret[1])
|
if (tls_derive_master_secret(conn) != 1
|
||||||
!= TLS_protocol_tlcp) {
|
|| tls_derive_key_block(conn) != 1
|
||||||
error_print();
|
|| tls_init_application_keys(conn) != 1) {
|
||||||
tls_send_alert(conn, TLS_alert_decrypt_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
|
|
||||||
|
|
||||||
if (tlcp_generate_keys(conn) != 1) {
|
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -2354,7 +2176,7 @@ int tlcp_recv_client_finished(TLS_CONNECT *conn)
|
|||||||
if (tls_compute_verify_data(conn->digest, conn->master_secret, "client finished",
|
if (tls_compute_verify_data(conn->digest, conn->master_secret, "client finished",
|
||||||
&conn->dgst_ctx, local_verify_data) != 1) {
|
&conn->dgst_ctx, local_verify_data) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_internal_error);
|
tls12_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2368,15 +2190,15 @@ int tlcp_recv_client_finished(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
if (tls_record_protocol(conn->record) != conn->protocol) {
|
if (tls_record_protocol(conn->record) != conn->protocol) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_unexpected_message);
|
tls12_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (tlcp_record_decrypt(conn->cipher_suite,
|
if (tls_record_decrypt(conn->cipher_suite,
|
||||||
&conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv,
|
&conn->client_write_mac_ctx, &conn->client_write_key, conn->client_write_iv,
|
||||||
conn->client_seq_num, conn->record, conn->recordlen,
|
conn->client_seq_num, conn->record, conn->recordlen,
|
||||||
conn->plain_record, &conn->plain_recordlen) != 1) {
|
conn->plain_record, &conn->plain_recordlen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_bad_record_mac);
|
tls12_send_alert(conn, TLS_alert_bad_record_mac);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tls_seq_num_incr(conn->client_seq_num);
|
tls_seq_num_incr(conn->client_seq_num);
|
||||||
@@ -2386,13 +2208,13 @@ int tlcp_recv_client_finished(TLS_CONNECT *conn)
|
|||||||
|
|
||||||
if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) {
|
if (tls_record_get_handshake_finished(conn->plain_record, &verify_data, &verify_data_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_unexpected_message);
|
tls12_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (verify_data_len != sizeof(local_verify_data)
|
if (verify_data_len != sizeof(local_verify_data)
|
||||||
|| memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) {
|
|| memcmp(verify_data, local_verify_data, sizeof(local_verify_data)) != 0) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_decrypt_error);
|
tls12_send_alert(conn, TLS_alert_decrypt_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2416,7 +2238,7 @@ int tlcp_send_server_finished(TLS_CONNECT *conn)
|
|||||||
if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished",
|
if (tls_compute_verify_data(conn->digest, conn->master_secret, "server finished",
|
||||||
&conn->dgst_ctx, verify_data) != 1) {
|
&conn->dgst_ctx, verify_data) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_internal_error);
|
tls12_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2425,18 +2247,18 @@ int tlcp_send_server_finished(TLS_CONNECT *conn)
|
|||||||
if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen,
|
if (tls_record_set_handshake_finished(conn->plain_record, &conn->plain_recordlen,
|
||||||
verify_data, sizeof(verify_data)) != 1) {
|
verify_data, sizeof(verify_data)) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_internal_error);
|
tls12_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (conn->verbose)
|
if (conn->verbose)
|
||||||
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
|
||||||
|
|
||||||
if (tlcp_record_encrypt(conn->cipher_suite,
|
if (tls_record_encrypt(conn->cipher_suite,
|
||||||
&conn->server_write_mac_ctx, &conn->server_write_key, conn->server_write_iv,
|
&conn->server_write_mac_ctx, &conn->server_write_key, conn->server_write_iv,
|
||||||
conn->server_seq_num, conn->plain_record, conn->plain_recordlen,
|
conn->server_seq_num, conn->plain_record, conn->plain_recordlen,
|
||||||
conn->record, &conn->recordlen) != 1) {
|
conn->record, &conn->recordlen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tlcp_send_alert(conn, TLS_alert_internal_error);
|
tls12_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tls_seq_num_incr(conn->server_seq_num);
|
tls_seq_num_incr(conn->server_seq_num);
|
||||||
@@ -2564,98 +2386,6 @@ int tlcp_send(TLS_CONNECT *conn, const uint8_t *in, size_t inlen, size_t *sentle
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tlcp_send_encrypted_alert(TLS_CONNECT *conn, int level, int alert)
|
|
||||||
{
|
|
||||||
const HMAC_CTX *hmac;
|
|
||||||
const BLOCK_CIPHER_KEY *key;
|
|
||||||
const uint8_t *iv;
|
|
||||||
uint8_t *seq_num;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!conn) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!tls_alert_level_name(level) || !tls_alert_description_text(alert)) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (conn->send_state && conn->send_state != TLS_state_send_record) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (conn->send_state == TLS_state_send_record
|
|
||||||
&& tls_record_type(conn->record) != TLS_record_alert) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!conn->send_state) {
|
|
||||||
tls_clean_record(conn);
|
|
||||||
conn->plain_recordlen = 0;
|
|
||||||
|
|
||||||
if (conn->is_client) {
|
|
||||||
hmac = &conn->client_write_mac_ctx;
|
|
||||||
key = &conn->client_write_key;
|
|
||||||
iv = conn->client_write_iv;
|
|
||||||
seq_num = conn->client_seq_num;
|
|
||||||
} else {
|
|
||||||
hmac = &conn->server_write_mac_ctx;
|
|
||||||
key = &conn->server_write_key;
|
|
||||||
iv = conn->server_write_iv;
|
|
||||||
seq_num = conn->server_seq_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
tls_record_set_protocol(conn->plain_record, conn->protocol);
|
|
||||||
if (tls_record_set_alert(conn->plain_record, &conn->plain_recordlen, level, alert) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (conn->verbose) {
|
|
||||||
tlcp_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tlcp_record_encrypt(conn->cipher_suite, hmac, key, iv, seq_num,
|
|
||||||
conn->plain_record, conn->plain_recordlen,
|
|
||||||
conn->record, &conn->recordlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
conn->plain_recordlen = 0;
|
|
||||||
tls_clean_record(conn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
tls_seq_num_incr(seq_num);
|
|
||||||
conn->record_offset = 0;
|
|
||||||
conn->send_state = TLS_state_send_record;
|
|
||||||
|
|
||||||
if (conn->verbose) {
|
|
||||||
tls_encrypted_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = tls_send_record(conn);
|
|
||||||
if (ret != 1) {
|
|
||||||
if (ret != TLS_ERROR_SEND_AGAIN) {
|
|
||||||
error_print();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
conn->send_state = 0;
|
|
||||||
conn->plain_recordlen = 0;
|
|
||||||
tls_clean_record(conn);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tlcp_send_alert(TLS_CONNECT *conn, int alert)
|
|
||||||
{
|
|
||||||
return tlcp_send_encrypted_alert(conn, TLS_alert_level_fatal, alert);
|
|
||||||
}
|
|
||||||
|
|
||||||
int tlcp_send_warning(TLS_CONNECT *conn, int alert)
|
|
||||||
{
|
|
||||||
return tlcp_send_encrypted_alert(conn, TLS_alert_level_warning, alert);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Client Server
|
Client Server
|
||||||
@@ -2902,7 +2632,6 @@ int tlcp_server_handshake(TLS_CONNECT *conn)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
||||||
while (conn->handshake_state != TLS_state_handshake_over) {
|
while (conn->handshake_state != TLS_state_handshake_over) {
|
||||||
|
|
||||||
ret = tlcp_do_server_handshake(conn);
|
ret = tlcp_do_server_handshake(conn);
|
||||||
|
|||||||
199
src/tls.c
199
src/tls.c
@@ -789,21 +789,6 @@ int tls_prf(const DIGEST *digest, const uint8_t *secret, size_t secretlen, const
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_pre_master_secret_generate(uint8_t pre_master_secret[48], int protocol)
|
|
||||||
{
|
|
||||||
if (!tls_protocol_name(protocol)) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
pre_master_secret[0] = (uint8_t)(protocol >> 8);
|
|
||||||
pre_master_secret[1] = (uint8_t)(protocol);
|
|
||||||
if (rand_bytes(pre_master_secret + 2, 46) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48],
|
int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48],
|
||||||
const char *label, const DIGEST_CTX *dgst_ctx, uint8_t verify_data[12])
|
const char *label, const DIGEST_CTX *dgst_ctx, uint8_t verify_data[12])
|
||||||
{
|
{
|
||||||
@@ -837,63 +822,83 @@ int tls_compute_verify_data(const DIGEST *digest, const uint8_t master_secret[48
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tls_generate_pre_master_secret(TLS_CONNECT *conn,
|
|
||||||
uint8_t *pre_master_secret, size_t *pre_master_secret_len)
|
|
||||||
|
|
||||||
|
int tls_derive_pre_master_secret(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
if (!conn || !pre_master_secret || !pre_master_secret_len) {
|
if (!conn || conn->peer_key_exchange_len != 65) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (x509_key_exchange(&conn->key_exchanges[0], conn->peer_key_exchange,
|
if (x509_key_exchange(&conn->key_exchanges[0], conn->peer_key_exchange,
|
||||||
conn->peer_key_exchange_len, pre_master_secret, pre_master_secret_len) != 1) {
|
conn->peer_key_exchange_len, conn->pre_master_secret, &conn->pre_master_secret_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (*pre_master_secret_len != 32) {
|
if (conn->pre_master_secret_len != 32) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (conn->verbose >= 5) {
|
|
||||||
format_bytes(stderr, 0, 0, "pre_master_secret", pre_master_secret, *pre_master_secret_len);
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tls_generate_master_secret(TLS_CONNECT *conn,
|
int tls_derive_master_secret(TLS_CONNECT *conn)
|
||||||
const uint8_t *pre_master_secret, size_t pre_master_secret_len)
|
|
||||||
{
|
{
|
||||||
if (!conn || !pre_master_secret || pre_master_secret_len != 32) {
|
if (!conn || !conn->digest) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (tls_prf(conn->digest, pre_master_secret, pre_master_secret_len,
|
switch (conn->protocol) {
|
||||||
"master secret",
|
case TLS_protocol_tlcp:
|
||||||
conn->client_random, 32,
|
if (conn->pre_master_secret_len != 48) {
|
||||||
conn->server_random, 32,
|
error_print();
|
||||||
48, conn->master_secret) != 1) {
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TLS_protocol_tls12:
|
||||||
|
if (conn->pre_master_secret_len != 32) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (conn->verbose >= 5) {
|
if (tls_prf(conn->digest, conn->pre_master_secret, conn->pre_master_secret_len,
|
||||||
|
"master secret",
|
||||||
|
conn->client_random, 32,
|
||||||
|
conn->server_random, 32,
|
||||||
|
48, conn->master_secret) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (conn->verbose == 5) {
|
||||||
format_bytes(stderr, 0, 0, "master_secret", conn->master_secret, 48);
|
format_bytes(stderr, 0, 0, "master_secret", conn->master_secret, 48);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tls_generate_key_block(TLS_CONNECT *conn)
|
int tls_derive_key_block(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
size_t key_block_len;
|
if (!conn || !conn->cipher || !conn->digest) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (conn->cipher_suite) {
|
switch (conn->cipher_suite) {
|
||||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||||
key_block_len = 96;
|
conn->key_block_len = (conn->cipher->key_size + conn->digest->digest_size) * 2;
|
||||||
|
assert(conn->key_block_len == 96);
|
||||||
break;
|
break;
|
||||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
||||||
key_block_len = 40;
|
conn->key_block_len = (conn->cipher->key_size + 4) * 2;
|
||||||
|
assert(conn->key_block_len == 40);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error_print();
|
error_print();
|
||||||
@@ -901,68 +906,86 @@ static int tls_generate_key_block(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tls_prf(conn->digest, conn->master_secret, 48, "key expansion",
|
if (tls_prf(conn->digest, conn->master_secret, 48, "key expansion",
|
||||||
conn->server_random, 32,
|
conn->server_random, 32,
|
||||||
conn->client_random, 32,
|
conn->client_random, 32,
|
||||||
key_block_len, conn->key_block) != 1) {
|
conn->key_block_len, conn->key_block) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->verbose >= 5) {
|
if (conn->verbose == 5) {
|
||||||
format_bytes(stderr, 0, 0, "key_blocks", conn->key_block, key_block_len);
|
format_bytes(stderr, 0, 0, "key_blocks", conn->key_block, conn->key_block_len);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tls_generate_record_keys(TLS_CONNECT *conn)
|
int tls_init_application_keys(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
|
size_t keylen;
|
||||||
|
|
||||||
|
if (!conn || !conn->cipher || !conn->digest || !conn->key_block_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
keylen = conn->cipher->key_size;
|
||||||
|
|
||||||
switch (conn->cipher_suite) {
|
switch (conn->cipher_suite) {
|
||||||
|
case TLS_cipher_ecc_sm4_cbc_sm3:
|
||||||
|
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
||||||
|
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
||||||
|
{
|
||||||
|
size_t dgstlen = conn->digest->digest_size;
|
||||||
|
|
||||||
|
if (hmac_init(&conn->client_write_mac_ctx, conn->digest,
|
||||||
|
conn->key_block, dgstlen) != 1
|
||||||
|
|| hmac_init(&conn->server_write_mac_ctx, conn->digest,
|
||||||
|
conn->key_block + dgstlen, dgstlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (conn->is_client) {
|
||||||
|
if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher,
|
||||||
|
conn->key_block + dgstlen * 2) != 1
|
||||||
|
|| block_cipher_set_decrypt_key(&conn->server_write_key, conn->cipher,
|
||||||
|
conn->key_block + dgstlen * 2 + keylen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (block_cipher_set_decrypt_key(&conn->client_write_key, conn->cipher,
|
||||||
|
conn->key_block + dgstlen * 2) != 1
|
||||||
|
|| block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher,
|
||||||
|
conn->key_block + dgstlen * 2 + keylen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (conn->verbose >= 5) {
|
||||||
|
format_bytes(stderr, 0, 0, "client_write_mac_key", conn->key_block, dgstlen);
|
||||||
|
format_bytes(stderr, 0, 0, "server_write_mac_key", conn->key_block + dgstlen, dgstlen);
|
||||||
|
format_bytes(stderr, 0, 0, "client_write_key", conn->key_block + dgstlen * 2, keylen);
|
||||||
|
format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + dgstlen * 2 + keylen, keylen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case TLS_cipher_ecc_sm4_gcm_sm3:
|
case TLS_cipher_ecc_sm4_gcm_sm3:
|
||||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
||||||
if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block) != 1
|
if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block) != 1
|
||||||
|| block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 16) != 1) {
|
|| block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + keylen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(conn->client_write_iv, 0, sizeof(conn->client_write_iv));
|
memset(conn->client_write_iv, 0, sizeof(conn->client_write_iv));
|
||||||
memset(conn->server_write_iv, 0, sizeof(conn->server_write_iv));
|
memset(conn->server_write_iv, 0, sizeof(conn->server_write_iv));
|
||||||
memcpy(conn->client_write_iv, conn->key_block + 32, 4);
|
memcpy(conn->client_write_iv, conn->key_block + keylen * 2, 4);
|
||||||
memcpy(conn->server_write_iv, conn->key_block + 36, 4);
|
memcpy(conn->server_write_iv, conn->key_block + keylen * 2 + 4, 4);
|
||||||
if (conn->verbose >= 5) {
|
if (conn->verbose >= 5) {
|
||||||
format_bytes(stderr, 0, 0, "client_write_key", conn->key_block, 16);
|
format_bytes(stderr, 0, 0, "client_write_key", conn->key_block, keylen);
|
||||||
format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + 16, 16);
|
format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + keylen, keylen);
|
||||||
format_bytes(stderr, 0, 0, "client_write_iv", conn->key_block + 32, 4);
|
format_bytes(stderr, 0, 0, "client_write_iv", conn->key_block + keylen * 2, 4);
|
||||||
format_bytes(stderr, 0, 0, "server_write_iv", conn->key_block + 36, 4);
|
format_bytes(stderr, 0, 0, "server_write_iv", conn->key_block + keylen * 2 + 4, 4);
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TLS_cipher_ecc_sm4_cbc_sm3:
|
|
||||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
|
||||||
if (hmac_init(&conn->client_write_mac_ctx, conn->digest, conn->key_block, 32) != 1
|
|
||||||
|| hmac_init(&conn->server_write_mac_ctx, conn->digest, conn->key_block + 32, 32) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (conn->is_client) {
|
|
||||||
if (block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1
|
|
||||||
|| block_cipher_set_decrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (block_cipher_set_decrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64) != 1
|
|
||||||
|| block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (conn->verbose >= 5) {
|
|
||||||
format_bytes(stderr, 0, 0, "client_write_mac_key", conn->key_block, 32);
|
|
||||||
format_bytes(stderr, 0, 0, "server_write_mac_key", conn->key_block + 32, 32);
|
|
||||||
format_bytes(stderr, 0, 0, "client_write_key", conn->key_block + 64, 16);
|
|
||||||
format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + 80, 16);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -970,28 +993,13 @@ static int tls_generate_record_keys(TLS_CONNECT *conn)
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tls_generate_keys(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
uint8_t pre_master_secret[32];
|
|
||||||
size_t pre_master_secret_len;
|
|
||||||
|
|
||||||
if (tls_generate_pre_master_secret(conn, pre_master_secret, &pre_master_secret_len) != 1
|
|
||||||
|| tls_generate_master_secret(conn, pre_master_secret, pre_master_secret_len) != 1
|
|
||||||
|| tls_generate_key_block(conn) != 1
|
|
||||||
|| tls_generate_record_keys(conn) != 1) {
|
|
||||||
gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret));
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret));
|
|
||||||
tls_seq_num_reset(conn->client_seq_num);
|
tls_seq_num_reset(conn->client_seq_num);
|
||||||
tls_seq_num_reset(conn->server_seq_num);
|
tls_seq_num_reset(conn->server_seq_num);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int tls_client_verify_init(TLS_CLIENT_VERIFY_CTX *ctx)
|
int tls_client_verify_init(TLS_CLIENT_VERIFY_CTX *ctx)
|
||||||
{
|
{
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
@@ -1124,9 +1132,6 @@ int tls_compression_methods_has_null_compression(const uint8_t *meths, size_t me
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int tls_record_encrypt(int cipher_suite,
|
int tls_record_encrypt(int cipher_suite,
|
||||||
const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
const HMAC_CTX *hmac_ctx, const BLOCK_CIPHER_KEY *key, const uint8_t fixed_iv[4],
|
||||||
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
const uint8_t seq_num[8], const uint8_t *in, size_t inlen,
|
||||||
|
|||||||
145
src/tls12.c
145
src/tls12.c
@@ -22,8 +22,52 @@
|
|||||||
#include <gmssl/mem.h>
|
#include <gmssl/mem.h>
|
||||||
#include <gmssl/tls.h>
|
#include <gmssl/tls.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
TLS 1.2中,服务器和客户端的签名算法是独立的
|
||||||
|
有可能密码套件中的哈希函数是SHA256
|
||||||
|
服务器的签名算法是 ecdsa+sha512
|
||||||
|
客户端的签名算法是 ecdsa+sha384
|
||||||
|
|
||||||
|
|
||||||
|
客户端可以在ClientHello.signature_algorithms中限定服务器的签名算法
|
||||||
|
客户端要等到ServerKeyExchange时,才能确定服务器的签名算法是什么
|
||||||
|
这意味着,此时客户端才知道验证签名的transcript-hash到底是用什么计算出来的
|
||||||
|
|
||||||
|
|
||||||
|
ClientHello
|
||||||
|
ServerHello
|
||||||
|
server Certificate
|
||||||
|
ServerKeyExchange
|
||||||
|
CertificateRequest
|
||||||
|
ServerHelloDone
|
||||||
|
client Certificate
|
||||||
|
ClientKeyExchange
|
||||||
|
CertificateVerify
|
||||||
|
|
||||||
|
|
||||||
|
如果客户端发送了 ClientHello.signature_algorithms
|
||||||
|
那么服务器的 CertificateRequest.supported_signature_algorithms 必须是ClientHello.signature_algorithms的子集
|
||||||
|
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8 hash_algorithm;
|
||||||
|
uint8 signature_algorithm;
|
||||||
|
uint16 signature_length;
|
||||||
|
opaque signature[signature_length];
|
||||||
|
} CertificateVerify;
|
||||||
|
|
||||||
|
|
||||||
|
客户端CertificateVerify.(hash_algorithm+signature_algorithm) 必须是CertificateRequest.supported_signature_algorithms的子集
|
||||||
|
|
||||||
|
|
||||||
|
如果不进行客户端证书认证
|
||||||
|
服务器:
|
||||||
|
接收到ClientHello的时候,就能够确定自己的签名算法,也就是服务器一开始就可以确定hash算法
|
||||||
|
客户端:
|
||||||
|
ClientHello: 对服务器的签名算法限定
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
const int tls12_supported_groups[] = {
|
const int tls12_supported_groups[] = {
|
||||||
TLS_curve_sm2p256v1,
|
TLS_curve_sm2p256v1,
|
||||||
@@ -64,8 +108,6 @@ int tls12_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int f
|
|||||||
record, recordlen);
|
record, recordlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int tls_named_curve_oid(int named_curve)
|
int tls_named_curve_oid(int named_curve)
|
||||||
{
|
{
|
||||||
switch (named_curve) {
|
switch (named_curve) {
|
||||||
@@ -129,10 +171,6 @@ int tls12_record_get_handshake_client_key_exchange(const uint8_t *record,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct {
|
struct {
|
||||||
ClientCertificateType certificate_types<1..2^8-1>;
|
ClientCertificateType certificate_types<1..2^8-1>;
|
||||||
@@ -1255,7 +1293,6 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (client_verify)
|
if (client_verify)
|
||||||
tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5);
|
tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
@@ -2226,7 +2263,6 @@ int tls_send_server_hello_done(TLS_CONNECT *conn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 这是一个非常特殊的状态,其他的所有recv状态都是要读取的
|
// 这是一个非常特殊的状态,其他的所有recv状态都是要读取的
|
||||||
// 但是这个状态在大多数情况下,之前已经读取完了,但是我们无法判断这个信息
|
// 但是这个状态在大多数情况下,之前已经读取完了,但是我们无法判断这个信息
|
||||||
int tls_recv_server_hello_done(TLS_CONNECT *conn)
|
int tls_recv_server_hello_done(TLS_CONNECT *conn)
|
||||||
@@ -2345,44 +2381,59 @@ int tls_recv_client_certificate(TLS_CONNECT *conn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int tls_send_client_key_exchange(TLS_CONNECT *conn)
|
int tls_send_client_key_exchange(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (conn->recordlen == 0) {
|
if (conn->recordlen == 0) {
|
||||||
uint8_t point_octets[65];
|
uint8_t point_octets[65];
|
||||||
uint8_t *p = point_octets;
|
uint8_t *point_octets_ptr = point_octets;
|
||||||
size_t len = 0;
|
size_t point_octets_len = 0;
|
||||||
int curve_oid = tls_named_curve_oid(conn->key_exchange_group);
|
int curve_oid = tls_named_curve_oid(conn->key_exchange_group);
|
||||||
|
|
||||||
|
if (conn->verbose)
|
||||||
|
tls_trace("send ClientKeyExchange\n");
|
||||||
|
|
||||||
|
|
||||||
if (x509_key_generate(&conn->key_exchanges[0], OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) {
|
if (x509_key_generate(&conn->key_exchanges[0], OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (x509_public_key_to_bytes(&conn->key_exchanges[0], &p, &len) != 1) {
|
if (x509_public_key_to_bytes(&conn->key_exchanges[0], &point_octets_ptr, &point_octets_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (len != sizeof(point_octets)) {
|
if (point_octets_len != sizeof(point_octets)) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->verbose) tls_trace("send ClientKeyExchange\n");
|
|
||||||
if (tls12_record_set_handshake_client_key_exchange(conn->record, &conn->recordlen,
|
if (tls12_record_set_handshake_client_key_exchange(conn->record, &conn->recordlen,
|
||||||
point_octets, len) != 1) {
|
point_octets, point_octets_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
if (conn->verbose)
|
||||||
|
tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
||||||
|
|
||||||
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
|
if (conn->verbose)
|
||||||
|
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
|
||||||
|
|
||||||
|
if (conn->client_certs_len) {
|
||||||
|
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tls_derive_pre_master_secret(conn) != 1
|
||||||
|
|| tls_derive_master_secret(conn) != 1
|
||||||
|
|| tls_derive_key_block(conn) != 1
|
||||||
|
|| tls_init_application_keys(conn) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = tls_send_record(conn)) != 1) {
|
if ((ret = tls_send_record(conn)) != 1) {
|
||||||
@@ -2392,14 +2443,6 @@ int tls_send_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->client_certs_len)
|
|
||||||
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
|
||||||
|
|
||||||
if (tls_generate_keys(conn) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2409,19 +2452,29 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
const uint8_t *point_octets;
|
const uint8_t *point_octets;
|
||||||
size_t point_octets_len;
|
size_t point_octets_len;
|
||||||
|
|
||||||
if(conn->verbose) tls_trace("recv ClientKeyExchange\n");
|
|
||||||
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) {
|
||||||
error_print();
|
error_print();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if (conn->verbose)
|
||||||
|
tls_trace("recv ClientKeyExchange\n");
|
||||||
|
|
||||||
if (tls_record_protocol(conn->record) != conn->protocol) {
|
if (tls_record_protocol(conn->record) != conn->protocol) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
if (conn->verbose)
|
||||||
|
tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
||||||
|
|
||||||
|
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (conn->verbose)
|
||||||
|
tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
|
||||||
|
|
||||||
if (tls12_record_get_handshake_client_key_exchange(conn->record,
|
if (tls12_record_get_handshake_client_key_exchange(conn->record,
|
||||||
&point_octets, &point_octets_len) != 1) {
|
&point_octets, &point_octets_len) != 1) {
|
||||||
@@ -2433,25 +2486,19 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(conn->peer_key_exchange, point_octets, point_octets_len);
|
memcpy(conn->peer_key_exchange, point_octets, point_octets_len);
|
||||||
conn->peer_key_exchange_len = point_octets_len;
|
conn->peer_key_exchange_len = point_octets_len;
|
||||||
|
|
||||||
|
if (tls_derive_pre_master_secret(conn) != 1
|
||||||
if (digest_update(&conn->dgst_ctx, conn->record + 5, conn->recordlen - 5) != 1) {
|
|| tls_derive_master_secret(conn) != 1
|
||||||
|
|| tls_derive_key_block(conn) != 1
|
||||||
|
|| tls_init_application_keys(conn) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ClientKeyExchange", &conn->dgst_ctx);
|
|
||||||
|
|
||||||
|
if (conn->ctx->cacertslen) {
|
||||||
|
|
||||||
if (conn->ctx->cacertslen)
|
|
||||||
tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5);
|
tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
|
|
||||||
if (tls_generate_keys(conn) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2588,15 +2635,7 @@ int tls_send_change_cipher_spec(TLS_CONNECT *conn)
|
|||||||
int tls_recv_change_cipher_spec(TLS_CONNECT *conn)
|
int tls_recv_change_cipher_spec(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int (*send_alert)(TLS_CONNECT *conn, int alert) = tls_send_alert;
|
|
||||||
|
|
||||||
if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec) {
|
|
||||||
if (conn->protocol == TLS_protocol_tlcp) {
|
|
||||||
send_alert = tlcp_send_alert;
|
|
||||||
} else {
|
|
||||||
send_alert = tls12_send_alert;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -2608,14 +2647,20 @@ int tls_recv_change_cipher_spec(TLS_CONNECT *conn)
|
|||||||
|
|
||||||
if (tls_record_protocol(conn->record) != conn->protocol) {
|
if (tls_record_protocol(conn->record) != conn->protocol) {
|
||||||
error_print();
|
error_print();
|
||||||
send_alert(conn, TLS_alert_unexpected_message);
|
if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec)
|
||||||
|
tls12_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
|
else tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (conn->verbose)
|
||||||
|
tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
||||||
|
|
||||||
if(conn->verbose) tls12_record_print(stderr, conn->record, conn->recordlen, 0, 0);
|
|
||||||
if (tls_record_get_change_cipher_spec(conn->record) != 1) {
|
if (tls_record_get_change_cipher_spec(conn->record) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
send_alert(conn, TLS_alert_unexpected_message);
|
if (conn->is_client && conn->handshake_state == TLS_state_server_change_cipher_spec)
|
||||||
|
tls12_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
|
else tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ int tlcp_client_main(int argc, char *argv[])
|
|||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
certoutfile = *(++argv);
|
certoutfile = *(++argv);
|
||||||
} else if (!strcmp(*argv, "-verbose")) {
|
} else if (!strcmp(*argv, "-verbose")) {
|
||||||
verbose = 1;
|
verbose = 5;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -35,5 +35,5 @@
|
|||||||
" cat sm2signkey.pem > tlcpkey.pem\n"
|
" cat sm2signkey.pem > tlcpkey.pem\n"
|
||||||
" cat sm2enckey.pem >> tlcpkey.pem\n"
|
" cat sm2enckey.pem >> tlcpkey.pem\n"
|
||||||
"\n"
|
"\n"
|
||||||
" gmssl tlcp_server -port 4431 -cert tlcpcert.pem -key tlcpkey.pem -pass 1234\n"
|
" gmssl tlcp_server -port 4431 -cert tlcpcert.pem -key tlcpkey.pem -pass 1234 -cipher_suite TLS_ECC_SM4_CBC_SM3\n"
|
||||||
" gmssl tlcp_client -port 4431 -host 127.0.0.1 -cacert sm2rootcacert.pem\n"
|
" gmssl tlcp_client -port 4431 -host 127.0.0.1 -cacert sm2rootcacert.pem -cipher_suite TLS_ECC_SM4_CBC_SM3\n"
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ int tlcp_server_main(int argc , char **argv)
|
|||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
cacertfile = *(++argv);
|
cacertfile = *(++argv);
|
||||||
} else if (!strcmp(*argv, "-verbose")) {
|
} else if (!strcmp(*argv, "-verbose")) {
|
||||||
verbose = 1;
|
verbose = 5;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ int tls12_client_main(int argc, char *argv[])
|
|||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
infile = *(++argv);
|
infile = *(++argv);
|
||||||
} else if (!strcmp(*argv, "-verbose")) {
|
} else if (!strcmp(*argv, "-verbose")) {
|
||||||
verbose = 1;
|
verbose = 5;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ int tls12_server_main(int argc , char **argv)
|
|||||||
} else if (!strcmp(*argv, "-renegotiation_info")) {
|
} else if (!strcmp(*argv, "-renegotiation_info")) {
|
||||||
renegotiation_info = 1;
|
renegotiation_info = 1;
|
||||||
} else if (!strcmp(*argv, "-verbose")) {
|
} else if (!strcmp(*argv, "-verbose")) {
|
||||||
verbose = 1;
|
verbose = 5;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ int tls13_client_main(int argc, char *argv[])
|
|||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
infile = *(++argv);
|
infile = *(++argv);
|
||||||
} else if (!strcmp(*argv, "-verbose")) {
|
} else if (!strcmp(*argv, "-verbose")) {
|
||||||
verbose = 1;
|
verbose = 5;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ int tls13_server_main(int argc , char **argv)
|
|||||||
} else if (!strcmp(*argv, "-tls13_change_cipher_spec")) {
|
} else if (!strcmp(*argv, "-tls13_change_cipher_spec")) {
|
||||||
tls13_change_cipher_spec = 1;
|
tls13_change_cipher_spec = 1;
|
||||||
} else if (!strcmp(*argv, "-verbose")) {
|
} else if (!strcmp(*argv, "-verbose")) {
|
||||||
verbose = 1;
|
verbose = 5;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user