mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-20 03:44:15 +08:00
Refactor TLS
This commit is contained in:
@@ -77,7 +77,7 @@ option(ENABLE_SDF "Enable SDF module" OFF)
|
|||||||
|
|
||||||
option(ENABLE_ASM_UNDERSCORE_PREFIX "Add prefix `_` to assembly symbols" ON)
|
option(ENABLE_ASM_UNDERSCORE_PREFIX "Add prefix `_` to assembly symbols" ON)
|
||||||
|
|
||||||
option(ENABLE_TLS "Enable TLS and TLCP protocol support" ON)
|
option(ENABLE_TLS "Enable TLS and TLCP protocol support" OFF)
|
||||||
option(ENABLE_TLS_DEBUG "Enable TLS and TLCP print debug message" OFF)
|
option(ENABLE_TLS_DEBUG "Enable TLS and TLCP print debug message" OFF)
|
||||||
|
|
||||||
option (ENABLE_SM2_ENC_PRE_COMPUTE "Enable SM2 encryption precomputing" ON)
|
option (ENABLE_SM2_ENC_PRE_COMPUTE "Enable SM2 encryption precomputing" ON)
|
||||||
@@ -552,6 +552,7 @@ if (ENABLE_TLS)
|
|||||||
list(APPEND src
|
list(APPEND src
|
||||||
src/socket.c
|
src/socket.c
|
||||||
src/tls.c
|
src/tls.c
|
||||||
|
src/tls_cert.c
|
||||||
src/tls_alpn.c
|
src/tls_alpn.c
|
||||||
src/tls_ext.c
|
src/tls_ext.c
|
||||||
src/tls_psk.c
|
src/tls_psk.c
|
||||||
@@ -763,7 +764,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.1046")
|
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1047")
|
||||||
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)
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ int tls_uint8array_from_bytes(const uint8_t **data, size_t *datalen, const uint8
|
|||||||
int tls_uint16array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
|
int tls_uint16array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
|
||||||
int tls_uint24array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
|
int tls_uint24array_from_bytes(const uint8_t **data, size_t *datalen, const uint8_t **in, size_t *inlen);
|
||||||
int tls_length_is_zero(size_t len);
|
int tls_length_is_zero(size_t len);
|
||||||
int tls_uint16array_from_file(uint8_t *arr, size_t *arrlen, size_t maxlen, FILE *fp);
|
|
||||||
|
|
||||||
|
|
||||||
int tls_type_is_in_list(int cipher, const int *list, size_t list_count);
|
int tls_type_is_in_list(int cipher, const int *list, size_t list_count);
|
||||||
@@ -613,6 +612,20 @@ int tls_record_set_handshake_certificate(uint8_t *record, size_t *recordlen,
|
|||||||
int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, size_t *certslen);
|
int tls_record_get_handshake_certificate(const uint8_t *record, uint8_t *certs, size_t *certslen);
|
||||||
|
|
||||||
// ServerKeyExchange
|
// ServerKeyExchange
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TLS_server_key_exchange_ecdhe,
|
||||||
|
TLS_server_key_exchange_ecc,
|
||||||
|
TLS_server_key_exchange_ibsdh,
|
||||||
|
TLS_server_key_exchagne_ibc,
|
||||||
|
TLS_server_key_exchange_rsa,
|
||||||
|
};
|
||||||
|
|
||||||
|
int tls_server_ecdh_params_to_bytes(const X509_KEY *public_key, uint8_t **out, size_t *outlen);
|
||||||
|
int tls_server_ecdh_params_from_bytes(int *key_exchange_group,
|
||||||
|
const uint8_t **key_exchange, size_t *key_exchange_len,
|
||||||
|
const uint8_t **in, size_t *inlen);
|
||||||
|
|
||||||
int tls_server_key_exchange_print(FILE *fp, const uint8_t *ske, size_t skelen, int format, int indent);
|
int tls_server_key_exchange_print(FILE *fp, const uint8_t *ske, size_t skelen, int format, int indent);
|
||||||
|
|
||||||
#define TLS_MAX_SIGNATURE_SIZE SM2_MAX_SIGNATURE_SIZE
|
#define TLS_MAX_SIGNATURE_SIZE SM2_MAX_SIGNATURE_SIZE
|
||||||
@@ -622,6 +635,19 @@ int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
|
|||||||
int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
|
int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
|
||||||
const uint8_t client_random[32], const uint8_t server_random[32],
|
const uint8_t client_random[32], const uint8_t server_random[32],
|
||||||
int curve, const SM2_Z256_POINT *point, const uint8_t *sig, size_t siglen);
|
int curve, const SM2_Z256_POINT *point, const uint8_t *sig, size_t siglen);
|
||||||
|
|
||||||
|
|
||||||
|
int tls_record_set_handshake_server_key_exchange(uint8_t *record, size_t *recordlen,
|
||||||
|
int server_key_exchange_alg,
|
||||||
|
const uint8_t *server_ecdh_params, size_t server_ecdh_params_len,
|
||||||
|
int sig_alg, const uint8_t *sig, size_t siglen);
|
||||||
|
int tls_record_get_handshake_server_key_exchange(const uint8_t *record,
|
||||||
|
int server_key_exchange_alg,
|
||||||
|
const uint8_t **server_ecdh_params, size_t *server_ecdh_params_len,
|
||||||
|
int *sig_alg, const uint8_t **sig, size_t *siglen);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
int tls_record_set_handshake_server_key_exchange_ecdhe(uint8_t *record, size_t *recordlen,
|
int tls_record_set_handshake_server_key_exchange_ecdhe(uint8_t *record, size_t *recordlen,
|
||||||
int curve, const SM2_Z256_POINT *point, const uint8_t *sig, size_t siglen);
|
int curve, const SM2_Z256_POINT *point, const uint8_t *sig, size_t siglen);
|
||||||
int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record,
|
int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record,
|
||||||
@@ -629,6 +655,8 @@ int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record,
|
|||||||
int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen,
|
int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen,
|
||||||
int format, int indent);
|
int format, int indent);
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
int tlcp_record_set_handshake_server_key_exchange_ecc(uint8_t *record, size_t *recordlen,
|
int tlcp_record_set_handshake_server_key_exchange_ecc(uint8_t *record, size_t *recordlen,
|
||||||
const uint8_t *sig, size_t siglen);
|
const uint8_t *sig, size_t siglen);
|
||||||
int tlcp_record_get_handshake_server_key_exchange_ecc(const uint8_t *record,
|
int tlcp_record_get_handshake_server_key_exchange_ecc(const uint8_t *record,
|
||||||
@@ -643,15 +671,31 @@ int tlcp_server_key_exchange_ecc_print(FILE *fp, const uint8_t *sig, size_t sigl
|
|||||||
|
|
||||||
int tls_authorities_from_certs(uint8_t *ca_names, size_t *ca_names_len, size_t maxlen, const uint8_t *certs, size_t certslen);
|
int tls_authorities_from_certs(uint8_t *ca_names, size_t *ca_names_len, size_t maxlen, const uint8_t *certs, size_t certslen);
|
||||||
int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_namelen, const uint8_t *certs, size_t certslen);
|
int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_namelen, const uint8_t *certs, size_t certslen);
|
||||||
int tls_cert_types_accepted(const uint8_t *types, size_t types_len, const uint8_t *client_certs, size_t client_certs_len);
|
|
||||||
|
|
||||||
int tls_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen,
|
int tls_cert_types_has_ecdsa_sign(const uint8_t *types, size_t types_len);
|
||||||
|
|
||||||
|
|
||||||
|
// 这个函数应该提供的是int *, cnt 的输入输出?
|
||||||
|
// TLCP沿用了TLS 1.0/1.1的版本,TLS 1.2增加了supported_signature_algorithms
|
||||||
|
int tlcp_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen,
|
||||||
const uint8_t *cert_types, size_t cert_types_len,
|
const uint8_t *cert_types, size_t cert_types_len,
|
||||||
const uint8_t *ca_names, size_t ca_names_len);
|
const uint8_t *ca_names, size_t ca_names_len);
|
||||||
int tls_record_get_handshake_certificate_request(const uint8_t *record,
|
int tlcp_record_get_handshake_certificate_request(const uint8_t *record,
|
||||||
const uint8_t **cert_types, size_t *cert_types_len,
|
const uint8_t **cert_types, size_t *cert_types_len,
|
||||||
const uint8_t **ca_names, size_t *ca_names_len);
|
const uint8_t **ca_names, size_t *ca_names_len);
|
||||||
int tls_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
|
int tlcp_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
|
||||||
|
|
||||||
|
|
||||||
|
int tls12_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen,
|
||||||
|
const uint8_t *cert_types, size_t cert_types_len,
|
||||||
|
const uint8_t *sig_algs, size_t sig_algs_len,
|
||||||
|
const uint8_t *ca_names, size_t ca_names_len);
|
||||||
|
int tls12_record_get_handshake_certificate_request(const uint8_t *record,
|
||||||
|
const uint8_t **cert_types, size_t *cert_types_len,
|
||||||
|
const uint8_t **sig_algs, size_t *sig_algs_len,
|
||||||
|
const uint8_t **ca_names, size_t *ca_names_len);
|
||||||
|
int tls12_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ServerHelloDone
|
// ServerHelloDone
|
||||||
@@ -683,6 +727,9 @@ int tls_record_get_handshake_certificate_verify(const uint8_t *record,
|
|||||||
const uint8_t **sig, size_t *siglen);
|
const uint8_t **sig, size_t *siglen);
|
||||||
int tls_certificate_verify_print(FILE *fp, const uint8_t *p, size_t len, int format, int indent);
|
int tls_certificate_verify_print(FILE *fp, const uint8_t *p, size_t len, int format, int indent);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TLS_client_verify_client_hello = 0,
|
TLS_client_verify_client_hello = 0,
|
||||||
TLS_client_verify_server_hello = 1,
|
TLS_client_verify_server_hello = 1,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
|
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
* not use this file except in compliance with the License.
|
* not use this file except in compliance with the License.
|
||||||
@@ -17,9 +17,8 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Also update CPACK_PACKAGE_VERSION in CMakeLists.txt
|
|
||||||
#define GMSSL_VERSION_NUM 30200
|
#define GMSSL_VERSION_NUM 30200
|
||||||
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1046"
|
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1047"
|
||||||
|
|
||||||
int gmssl_version_num(void);
|
int gmssl_version_num(void);
|
||||||
const char *gmssl_version_str(void);
|
const char *gmssl_version_str(void);
|
||||||
|
|||||||
314
src/tlcp.c
314
src/tlcp.c
@@ -207,65 +207,6 @@ static int tlcp_server_ecc_params_from_bytes(const uint8_t **server_enc_cert,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tlcp_record_set_handshake_server_key_exchange_ecc(uint8_t *record, size_t *recordlen,
|
|
||||||
const uint8_t *sig, size_t siglen)
|
|
||||||
{
|
|
||||||
int type = TLS_handshake_server_key_exchange;
|
|
||||||
uint8_t *p;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
if (!record || !recordlen || !sig || !siglen) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (siglen > SM2_MAX_SIGNATURE_SIZE) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_record_protocol(record) != TLS_protocol_tlcp) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
p = tls_handshake_data(tls_record_data(record));
|
|
||||||
tls_uint16array_to_bytes(sig, siglen, &p, &len);
|
|
||||||
tls_record_set_handshake(record, recordlen, type, NULL, len);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tlcp_record_get_handshake_server_key_exchange_ecc(const uint8_t *record,
|
|
||||||
const uint8_t **sig, size_t *siglen)
|
|
||||||
{
|
|
||||||
int type;
|
|
||||||
const uint8_t *p;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
if (!record || !sig || !siglen) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_record_get_handshake(record, &type, &p, &len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (type != TLS_handshake_server_key_exchange) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_record_protocol(record) != TLS_protocol_tlcp) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (len) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tlcp_server_key_exchange_ecc_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent)
|
int tlcp_server_key_exchange_ecc_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent)
|
||||||
{
|
{
|
||||||
const uint8_t *sig;
|
const uint8_t *sig;
|
||||||
@@ -285,6 +226,151 @@ int tlcp_server_key_exchange_ecc_print(FILE *fp, const uint8_t *data, size_t dat
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tlcp_record_set_handshake_client_key_exchange(uint8_t *record, size_t *recordlen,
|
||||||
|
const uint8_t *enced_pms, size_t enced_pms_len)
|
||||||
|
{
|
||||||
|
int type = TLS_handshake_client_key_exchange;
|
||||||
|
uint8_t *p;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (!record || !recordlen || !enced_pms || !enced_pms_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (enced_pms_len > TLS_MAX_HANDSHAKE_DATA_SIZE - tls_uint16_size()) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p = tls_handshake_data(tls_record_data(record));
|
||||||
|
tls_uint16array_to_bytes(enced_pms, enced_pms_len, &p, &len);
|
||||||
|
tls_record_set_handshake(record, recordlen, type, NULL, len);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tlcp_record_get_handshake_client_key_exchange(const uint8_t *record,
|
||||||
|
const uint8_t **enced_pms, size_t *enced_pms_len)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
const uint8_t *cp;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!record || !enced_pms || !enced_pms_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_record_get_handshake(record, &type, &cp, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (type != TLS_handshake_client_key_exchange) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_uint16array_from_bytes(enced_pms, enced_pms_len, &cp, &len) != 1
|
||||||
|
|| tls_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct {
|
||||||
|
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>;
|
||||||
|
} CertificateRequest;
|
||||||
|
*/
|
||||||
|
int tlcp_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen,
|
||||||
|
const uint8_t *cert_types, size_t cert_types_len,
|
||||||
|
const uint8_t *ca_names, size_t ca_names_len)
|
||||||
|
{
|
||||||
|
int type = TLS_handshake_certificate_request;
|
||||||
|
uint8_t *p;
|
||||||
|
size_t len =0;
|
||||||
|
size_t datalen = 0;
|
||||||
|
|
||||||
|
if (!record || !recordlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (cert_types) {
|
||||||
|
if (cert_types_len == 0 || cert_types_len > TLS_MAX_CERTIFICATE_TYPES) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ca_names) {
|
||||||
|
if (ca_names_len == 0 || ca_names_len > TLS_MAX_CA_NAMES_SIZE) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tls_uint8array_to_bytes(cert_types, cert_types_len, NULL, &datalen);
|
||||||
|
tls_uint16array_to_bytes(ca_names, ca_names_len, NULL, &datalen);
|
||||||
|
if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p = tls_handshake_data(tls_record_data(record));
|
||||||
|
tls_uint8array_to_bytes(cert_types, cert_types_len, &p, &len);
|
||||||
|
tls_uint16array_to_bytes(ca_names, ca_names_len, &p, &len);
|
||||||
|
tls_record_set_handshake(record, recordlen, type, NULL, datalen);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tlcp_record_get_handshake_certificate_request(const uint8_t *record,
|
||||||
|
const uint8_t **cert_types, size_t *cert_types_len,
|
||||||
|
const uint8_t **ca_names, size_t *ca_names_len)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
const uint8_t *cp;
|
||||||
|
size_t len;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!record || !cert_types || !cert_types_len || !ca_names || !ca_names_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_record_get_handshake(record, &type, &cp, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (type != TLS_handshake_certificate_request) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_uint8array_from_bytes(cert_types, cert_types_len, &cp, &len) != 1
|
||||||
|
|| tls_uint16array_from_bytes(ca_names, ca_names_len, &cp, &len) != 1
|
||||||
|
|| tls_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*cert_types == NULL) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < *cert_types_len; i++) {
|
||||||
|
if (!tls_cert_type_name((*cert_types)[i])) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*ca_names) {
|
||||||
|
const uint8_t *names = *ca_names;
|
||||||
|
size_t nameslen = *ca_names_len;
|
||||||
|
while (nameslen) {
|
||||||
|
if (tls_uint16array_from_bytes(&cp, &len, &names, &nameslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ClientKeyExchange
|
ClientKeyExchange
|
||||||
@@ -756,6 +842,8 @@ int tlcp_recv_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
SM2_VERIFY_CTX verify_ctx;
|
SM2_VERIFY_CTX verify_ctx;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(conn->verbose) tls_trace("recv ServerKeyExchange\n");
|
if(conn->verbose) tls_trace("recv ServerKeyExchange\n");
|
||||||
|
|
||||||
if ((ret = tls_recv_record(conn)) != 1) {
|
if ((ret = tls_recv_record(conn)) != 1) {
|
||||||
@@ -772,12 +860,21 @@ int tlcp_recv_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlcp_record_get_handshake_server_key_exchange_ecc(conn->record, &sig, &siglen) != 1) {
|
if (tls_record_get_handshake_server_key_exchange(conn->record,
|
||||||
|
TLS_server_key_exchange_ecc, NULL, 0,
|
||||||
|
&conn->sig_alg, &sig, &siglen) != 1) {
|
||||||
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->sig_alg != TLS_sig_sm2sig_sm3) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_illegal_parameter);
|
||||||
|
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;
|
||||||
@@ -885,7 +982,7 @@ int tlcp_recv_certificate_request(TLS_CONNECT *conn)
|
|||||||
if(conn->verbose) tls_trace("recv CertificateRequest\n");
|
if(conn->verbose) tls_trace("recv CertificateRequest\n");
|
||||||
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
||||||
|
|
||||||
if (tls_record_get_handshake_certificate_request(conn->record,
|
if (tlcp_record_get_handshake_certificate_request(conn->record,
|
||||||
&cert_types, &cert_types_len, &ca_names, &ca_names_len) != 1) {
|
&cert_types, &cert_types_len, &ca_names, &ca_names_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
@@ -897,8 +994,7 @@ int tlcp_recv_certificate_request(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 这里根据cipher_suite判断请求的类型是否合适
|
if (tls_cert_types_has_ecdsa_sign(cert_types, cert_types_len) != 1) {
|
||||||
if (tls_cert_types_accepted(cert_types, cert_types_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);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1030,8 +1126,12 @@ int tlcp_send_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sm2_encrypt(&conn->server_enc_key.u.sm2_key, conn->pre_master_secret, 48,
|
if (sm2_encrypt(&conn->server_enc_key.u.sm2_key, conn->pre_master_secret, 48,
|
||||||
enced_pre_master_secret, &enced_pre_master_secret_len) != 1
|
enced_pre_master_secret, &enced_pre_master_secret_len) != 1) {
|
||||||
|| tls_record_set_handshake_client_key_exchange_pke(conn->record, &conn->recordlen,
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tlcp_record_set_handshake_client_key_exchange(conn->record, &conn->recordlen,
|
||||||
enced_pre_master_secret, enced_pre_master_secret_len) != 1) {
|
enced_pre_master_secret, enced_pre_master_secret_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
@@ -1779,8 +1879,6 @@ int tlcp_send_server_certificate(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 这个也有这个问题,要考虑兼容SM9
|
|
||||||
int tlcp_send_server_key_exchange(TLS_CONNECT *conn)
|
int tlcp_send_server_key_exchange(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
SM2_SIGN_CTX sign_ctx;
|
SM2_SIGN_CTX sign_ctx;
|
||||||
@@ -1835,7 +1933,8 @@ int tlcp_send_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tlcp_record_set_handshake_server_key_exchange_ecc(conn->record, &conn->recordlen, sigbuf, siglen) != 1) {
|
if (tls_record_set_handshake_server_key_exchange(conn->record, &conn->recordlen,
|
||||||
|
TLS_server_key_exchange_ecc, NULL, 0, conn->sig_alg, sigbuf, siglen) != 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;
|
||||||
@@ -2042,50 +2141,47 @@ int tlcp_send_certificate_request(TLS_CONNECT *conn)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((ret = tls_send_certificate_request(conn)) != 1) {
|
// 如果要进行客户端证书验证,服务器要提供验证的证书,但是所有证书的
|
||||||
|
const uint8_t cert_types[] = { TLS_cert_type_ecdsa_sign };
|
||||||
|
uint8_t ca_names[TLS_MAX_CA_NAMES_SIZE] = {0}; // TODO: 根据客户端验证CA证书列计算缓冲大小,或直接输出到record缓冲
|
||||||
|
size_t ca_names_len = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (!conn->client_certificate_verify) {
|
||||||
error_print();
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->recordlen == 0) {
|
||||||
|
if(conn->verbose) tls_trace("send CertificateRequest\n");
|
||||||
|
if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names),
|
||||||
|
conn->ctx->cacerts, conn->ctx->cacertslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tlcp_record_set_handshake_certificate_request(conn->record, &conn->recordlen,
|
||||||
|
cert_types, sizeof(cert_types),
|
||||||
|
ca_names, ca_names_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = tls_send_record(conn)) != 1) {
|
||||||
|
if (ret != TLS_ERROR_SEND_AGAIN) {
|
||||||
|
error_print();
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
|
tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tlcp_send_server_hello_done(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if ((ret = tls_send_server_hello_done(conn)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int tlcp_recv_client_certificate(TLS_CONNECT *conn)
|
int tlcp_recv_client_certificate(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
@@ -2121,7 +2217,7 @@ int tlcp_recv_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
tlcp_record_print(stderr, 0, 0, conn->record, conn->recordlen);
|
||||||
|
|
||||||
if (tls_record_get_handshake_client_key_exchange_pke(conn->record, &enced_pms, &enced_pms_len) != 1) {
|
if (tlcp_record_get_handshake_client_key_exchange(conn->record, &enced_pms, &enced_pms_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -2441,7 +2537,7 @@ int tlcp_do_server_handshake(TLS_CONNECT *conn)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TLS_state_server_hello_done:
|
case TLS_state_server_hello_done:
|
||||||
ret = tlcp_send_server_hello_done(conn);
|
ret = tls_send_server_hello_done(conn);
|
||||||
if (conn->client_certificate_verify)
|
if (conn->client_certificate_verify)
|
||||||
next_state = TLS_state_client_certificate;
|
next_state = TLS_state_client_certificate;
|
||||||
else next_state = TLS_state_client_key_exchange;
|
else next_state = TLS_state_client_key_exchange;
|
||||||
|
|||||||
751
src/tls12.c
751
src/tls12.c
@@ -162,117 +162,6 @@ int tls12_record_decrypt(int cipher_suite, const HMAC_CTX *hmac_ctx,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// modify: conn->record_offset
|
|
||||||
int tls_send_record(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
size_t left;
|
|
||||||
tls_ret_t n;
|
|
||||||
|
|
||||||
left = tls_record_length(conn->record) - conn->record_offset;
|
|
||||||
while (left) {
|
|
||||||
n = tls_socket_send(conn->sock, conn->record + conn->record_offset, left, 0);
|
|
||||||
if (n < 0) {
|
|
||||||
int err = tls_socket_get_error();
|
|
||||||
tls_socket_err_t type = tls_socket_get_error_type(err, 0);
|
|
||||||
if (type == TLS_SOCKET_ERR_WANT_WRITE) {
|
|
||||||
return TLS_ERROR_SEND_AGAIN;
|
|
||||||
} else if (type == TLS_SOCKET_ERR_INTERRUPTED) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
error_print();
|
|
||||||
return TLS_ERROR_SYSCALL;
|
|
||||||
}
|
|
||||||
} else if (n == 0) {
|
|
||||||
return TLS_ERROR_TCP_CLOSED;
|
|
||||||
}
|
|
||||||
conn->record_offset += n;
|
|
||||||
left -= n;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tls_recv_record(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
size_t left;
|
|
||||||
tls_ret_t n;
|
|
||||||
|
|
||||||
if (conn->recordlen) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->record_offset < 5) {
|
|
||||||
left = 5 - conn->record_offset;
|
|
||||||
while (left) {
|
|
||||||
n = tls_socket_recv(conn->sock, conn->record + conn->record_offset, left, 0);
|
|
||||||
if (n < 0) {
|
|
||||||
int err = tls_socket_get_error();
|
|
||||||
tls_socket_err_t type = tls_socket_get_error_type(err, 1);
|
|
||||||
if (type == TLS_SOCKET_ERR_WANT_READ) {
|
|
||||||
return TLS_ERROR_RECV_AGAIN;
|
|
||||||
} else if (type == TLS_SOCKET_ERR_INTERRUPTED) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
error_print();
|
|
||||||
// TODO: check the usage of OpenSSL SSL_ERR_SYSCALL
|
|
||||||
// if applications such as Nginx, HTTPD do not use this error, we just return -1
|
|
||||||
return TLS_ERROR_SYSCALL;
|
|
||||||
}
|
|
||||||
} else if (n == 0) {
|
|
||||||
return TLS_ERROR_TCP_CLOSED;
|
|
||||||
}
|
|
||||||
conn->record_offset += n;
|
|
||||||
left -= n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->record_offset == 5) {
|
|
||||||
if (!tls_record_type_name(tls_record_type(conn->record))) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!tls_protocol_name(tls_record_protocol(conn->record))) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_record_length(conn->record) > TLS_MAX_RECORD_SIZE) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->record_offset >= tls_record_length(conn->record)) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
left = tls_record_length(conn->record) - conn->record_offset;
|
|
||||||
while (left) {
|
|
||||||
n = tls_socket_recv(conn->sock, conn->record + conn->record_offset, left, 0);
|
|
||||||
if (n < 0) {
|
|
||||||
int err = tls_socket_get_error();
|
|
||||||
tls_socket_err_t type = tls_socket_get_error_type(err, 1);
|
|
||||||
if (type == TLS_SOCKET_ERR_WANT_READ) {
|
|
||||||
return TLS_ERROR_RECV_AGAIN;
|
|
||||||
} else if (type == TLS_SOCKET_ERR_INTERRUPTED) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
error_print();
|
|
||||||
return TLS_ERROR_SYSCALL;
|
|
||||||
}
|
|
||||||
} else if (n == 0) {
|
|
||||||
return TLS_ERROR_TCP_CLOSED;
|
|
||||||
}
|
|
||||||
conn->record_offset += n;
|
|
||||||
left -= n;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
conn->recordlen = conn->record_offset;
|
|
||||||
|
|
||||||
|
|
||||||
// 应该判断是否为Alert这种异常状况
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tls_named_curve_oid(int named_curve)
|
int tls_named_curve_oid(int named_curve)
|
||||||
{
|
{
|
||||||
@@ -293,233 +182,7 @@ int tls_named_curve_from_oid(int oid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int tls12_record_set_handshake_client_key_exchange(uint8_t *record, size_t *recordlen,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int tls_record_set_handshake_server_key_exchange(uint8_t *record, size_t *recordlen,
|
|
||||||
const uint8_t *server_ecdh_params, size_t server_ecdh_params_len,
|
|
||||||
uint16_t sig_alg, const uint8_t *sig, size_t siglen)
|
|
||||||
{
|
|
||||||
const int type = TLS_handshake_server_key_exchange;
|
|
||||||
uint8_t *p = tls_handshake_data(tls_record_data(record));
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
if (server_ecdh_params_len != 69) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (siglen > TLS_MAX_SIGNATURE_SIZE) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
tls_array_to_bytes(server_ecdh_params, server_ecdh_params_len, &p, &len);
|
|
||||||
tls_uint16_to_bytes(sig_alg, &p, &len);
|
|
||||||
tls_uint16array_to_bytes(sig, siglen, &p, &len);
|
|
||||||
tls_record_set_handshake(record, recordlen, type, NULL, len);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tls12_server_ecdh_params_from_bytes(uint8_t *curve_type, uint16_t *named_curve,
|
|
||||||
const uint8_t **point_octets, size_t *point_octets_len,
|
|
||||||
const uint8_t **in, size_t *inlen)
|
|
||||||
{
|
|
||||||
if (!curve_type || !named_curve || !point_octets || !point_octets_len
|
|
||||||
|| !in || !(*in) || !inlen) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_uint8_from_bytes(curve_type, in, inlen) != 1
|
|
||||||
|| tls_uint16_from_bytes(named_curve, in, inlen) != 1
|
|
||||||
|| tls_uint8array_from_bytes(point_octets, point_octets_len, in, inlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (*curve_type != TLS_curve_type_named_curve) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!tls_named_curve_name(*named_curve)) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!*point_octets || !*point_octets_len) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tls12_server_key_exchange_params_from_bytes(int cipher_suite,
|
|
||||||
const uint8_t **params, size_t *params_len, const uint8_t **in, size_t *inlen)
|
|
||||||
{
|
|
||||||
const uint8_t *start;
|
|
||||||
|
|
||||||
if (!params || !params_len || !in || !(*in) || !inlen) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
start = *in;
|
|
||||||
switch (cipher_suite) {
|
|
||||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
|
||||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
|
||||||
#ifdef ENABLE_AES_CCM
|
|
||||||
case TLS_cipher_aes_128_ccm_sha256:
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
uint8_t curve_type;
|
|
||||||
uint16_t named_curve;
|
|
||||||
const uint8_t *point_octets;
|
|
||||||
size_t point_octets_len;
|
|
||||||
|
|
||||||
if (tls12_server_ecdh_params_from_bytes(&curve_type, &named_curve,
|
|
||||||
&point_octets, &point_octets_len, in, inlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*params = start;
|
|
||||||
*params_len = *in - start;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tls12_record_get_handshake_server_key_exchange(const uint8_t *record, int cipher_suite,
|
|
||||||
const uint8_t **params, size_t *params_len,
|
|
||||||
uint16_t *sig_alg, const uint8_t **sig, size_t *siglen)
|
|
||||||
{
|
|
||||||
int type;
|
|
||||||
const uint8_t *p;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
if (!record || !params || !params_len || !sig_alg || !sig || !siglen) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_record_get_handshake(record, &type, &p, &len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (type != TLS_handshake_server_key_exchange) {
|
|
||||||
error_print();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tls12_server_key_exchange_params_from_bytes(cipher_suite,
|
|
||||||
params, params_len, &p, &len) != 1
|
|
||||||
|| tls_uint16_from_bytes(sig_alg, &p, &len) != 1
|
|
||||||
|| tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1
|
|
||||||
|| tls_length_is_zero(len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!tls_signature_scheme_name(*sig_alg)) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 这个函数是有问题的,因为tlcp的格式和TLS不一样
|
|
||||||
int tls_record_get_handshake_server_key_exchange(const uint8_t *record,
|
|
||||||
uint8_t *curve_type, uint16_t *named_curve,
|
|
||||||
const uint8_t **point_octets, size_t *point_octets_len,
|
|
||||||
const uint8_t **server_ecdh_params, size_t *server_ecdh_params_len,
|
|
||||||
uint16_t *sig_alg, const uint8_t **sig, size_t *siglen)
|
|
||||||
{
|
|
||||||
int type;
|
|
||||||
const uint8_t *p;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
if (tls_record_get_handshake(record, &type, &p, &len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (type != TLS_handshake_server_key_exchange) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*server_ecdh_params = p;
|
|
||||||
if (tls12_server_ecdh_params_from_bytes(curve_type, named_curve,
|
|
||||||
point_octets, point_octets_len, &p, &len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*server_ecdh_params_len = p - *server_ecdh_params;
|
|
||||||
if (*server_ecdh_params_len != 69) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_uint16_from_bytes(sig_alg, &p, &len) != 1
|
|
||||||
|| tls_uint16array_from_bytes(sig, siglen, &p, &len) != 1
|
|
||||||
|| tls_length_is_zero(len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!tls_signature_scheme_name(*sig_alg)) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tls12_server_ecdh_params_to_bytes(const X509_KEY *key, uint8_t **out, size_t *outlen)
|
|
||||||
{
|
|
||||||
int named_curve;
|
|
||||||
uint8_t point[256];
|
|
||||||
uint8_t *pp = point;
|
|
||||||
size_t point_len = 0;
|
|
||||||
|
|
||||||
if (!key || !outlen) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (key->algor != OID_ec_public_key
|
|
||||||
|| !(named_curve = tls_named_curve_from_oid(key->algor_param))) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (x509_public_key_to_bytes(key, &pp, &point_len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (point_len != 65) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tls_uint8_to_bytes(TLS_curve_type_named_curve, out, outlen);
|
|
||||||
tls_uint16_to_bytes((uint16_t)named_curve, out, outlen);
|
|
||||||
tls_uint8array_to_bytes(point, point_len, out, outlen);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tls_record_set_handshake_client_key_exchange(uint8_t *record, size_t *recordlen,
|
|
||||||
const uint8_t *point_octets, size_t point_octets_len)
|
const uint8_t *point_octets, size_t point_octets_len)
|
||||||
{
|
{
|
||||||
int type = TLS_handshake_client_key_exchange;
|
int type = TLS_handshake_client_key_exchange;
|
||||||
@@ -531,11 +194,12 @@ int tls_record_set_handshake_client_key_exchange(uint8_t *record, size_t *record
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tls_uint8array_to_bytes(point_octets, (uint8_t)point_octets_len, &p, &len);
|
tls_uint8array_to_bytes(point_octets, (uint8_t)point_octets_len, &p, &len);
|
||||||
|
|
||||||
tls_record_set_handshake(record, recordlen, type, NULL, len);
|
tls_record_set_handshake(record, recordlen, type, NULL, len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_record_get_handshake_client_key_exchange(const uint8_t *record,
|
int tls12_record_get_handshake_client_key_exchange(const uint8_t *record,
|
||||||
const uint8_t **point_octets, size_t *point_octets_len)
|
const uint8_t **point_octets, size_t *point_octets_len)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
@@ -565,40 +229,103 @@ int tls_record_get_handshake_client_key_exchange(const uint8_t *record,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int tls12_cert_chains_select(const uint8_t *cert_chains, size_t cert_chains_len,
|
|
||||||
const int *supported_groups, size_t supported_groups_cnt, // optional
|
/*
|
||||||
const int *signature_algorithms, size_t signature_algorithms_cnt, // optional
|
struct {
|
||||||
const uint8_t *ca_names, size_t ca_names_len, // certificate_authorities optional
|
ClientCertificateType certificate_types<1..2^8-1>;
|
||||||
const uint8_t *host_name, size_t host_name_len, // optional, only in ClientHello
|
SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; // TLS 1.2 only
|
||||||
const uint8_t **certs, size_t *certs_len, size_t *certs_idx, int *prefered_sig_alg) // optional
|
DistinguishedName certificate_authorities<0..2^16-1>;
|
||||||
|
} CertificateRequest;
|
||||||
|
*/
|
||||||
|
int tls12_record_set_handshake_certificate_request(uint8_t *record, size_t *recordlen,
|
||||||
|
const uint8_t *cert_types, size_t cert_types_len,
|
||||||
|
const uint8_t *sig_algs, size_t sig_algs_len,
|
||||||
|
const uint8_t *ca_names, size_t ca_names_len)
|
||||||
{
|
{
|
||||||
|
int type = TLS_handshake_certificate_request;
|
||||||
|
uint8_t *p;
|
||||||
|
size_t len =0;
|
||||||
|
size_t datalen = 0;
|
||||||
|
|
||||||
|
if (!record || !recordlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (cert_types) {
|
||||||
|
if (cert_types_len == 0 || cert_types_len > TLS_MAX_CERTIFICATE_TYPES) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ca_names) {
|
||||||
|
if (ca_names_len == 0 || ca_names_len > TLS_MAX_CA_NAMES_SIZE) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tls_uint8array_to_bytes(cert_types, cert_types_len, NULL, &datalen);
|
||||||
|
tls_uint16array_to_bytes(ca_names, ca_names_len, NULL, &datalen);
|
||||||
|
if (datalen > TLS_MAX_HANDSHAKE_DATA_SIZE) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p = tls_handshake_data(tls_record_data(record));
|
||||||
|
tls_uint8array_to_bytes(cert_types, cert_types_len, &p, &len);
|
||||||
|
tls_uint16array_to_bytes(ca_names, ca_names_len, &p, &len);
|
||||||
|
tls_record_set_handshake(record, recordlen, type, NULL, datalen);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls12_record_get_handshake_certificate_request(const uint8_t *record,
|
||||||
|
const uint8_t **cert_types, size_t *cert_types_len,
|
||||||
|
const uint8_t **sig_algs, size_t *sig_algs_len,
|
||||||
|
const uint8_t **ca_names, size_t *ca_names_len)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
const uint8_t *cp;
|
||||||
|
size_t len;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (!cert_chains || !cert_chains_len) {
|
if (!record || !cert_types || !cert_types_len || !ca_names || !ca_names_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_record_get_handshake(record, &type, &cp, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (type != TLS_handshake_certificate_request) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_uint8array_from_bytes(cert_types, cert_types_len, &cp, &len) != 1
|
||||||
|
|| tls_uint16array_from_bytes(ca_names, ca_names_len, &cp, &len) != 1
|
||||||
|
|| tls_length_is_zero(len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; cert_chains_len; i++) {
|
if (*cert_types == NULL) {
|
||||||
const uint8_t *cert_chain;
|
|
||||||
size_t cert_chain_len;
|
|
||||||
int sig_alg;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (tls_uint24array_from_bytes(&cert_chain, &cert_chain_len,
|
|
||||||
&cert_chains, &cert_chains_len) != 1) {
|
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < *cert_types_len; i++) {
|
||||||
if (certs) *certs = cert_chain;
|
if (!tls_cert_type_name((*cert_types)[i])) {
|
||||||
if (certs_len) *certs_len = cert_chain_len;
|
error_print();
|
||||||
if (certs_idx) *certs_idx = i;
|
return -1;
|
||||||
if (prefered_sig_alg) *prefered_sig_alg = sig_alg;
|
}
|
||||||
|
}
|
||||||
|
if (*ca_names) {
|
||||||
|
const uint8_t *names = *ca_names;
|
||||||
|
size_t nameslen = *ca_names_len;
|
||||||
|
while (nameslen) {
|
||||||
|
if (tls_uint16array_from_bytes(&cp, &len, &names, &nameslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -611,6 +338,9 @@ int tls12_cert_chains_select(const uint8_t *cert_chains, size_t cert_chains_len,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void tls_clean_record(TLS_CONNECT *conn)
|
void tls_clean_record(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
conn->record_offset = 0;
|
conn->record_offset = 0;
|
||||||
@@ -684,8 +414,6 @@ static int tls12_cipher_suites_include_empty_renegotiation_info_scsv(
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 有可能需要支持SNI
|
|
||||||
|
|
||||||
int tls_send_client_hello(TLS_CONNECT *conn)
|
int tls_send_client_hello(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -2029,8 +1757,6 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int tls_send_server_key_exchange(TLS_CONNECT *conn)
|
int tls_send_server_key_exchange(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -2055,7 +1781,7 @@ int tls_send_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls12_server_ecdh_params_to_bytes(&conn->key_exchanges[0],
|
if (tls_server_ecdh_params_to_bytes(&conn->key_exchanges[0],
|
||||||
&p, &server_ecdh_params_len) != 1) {
|
&p, &server_ecdh_params_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
@@ -2082,6 +1808,7 @@ int tls_send_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
x509_sign_ctx_cleanup(&sign_ctx);
|
x509_sign_ctx_cleanup(&sign_ctx);
|
||||||
|
|
||||||
if (tls_record_set_handshake_server_key_exchange(conn->record, &conn->recordlen,
|
if (tls_record_set_handshake_server_key_exchange(conn->record, &conn->recordlen,
|
||||||
|
TLS_server_key_exchange_ecdhe,
|
||||||
server_ecdh_params, server_ecdh_params_len,
|
server_ecdh_params, server_ecdh_params_len,
|
||||||
conn->sig_alg, sig, siglen) != 1) {
|
conn->sig_alg, sig, siglen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -2191,9 +1918,15 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
uint16_t named_curve = 0;
|
uint16_t named_curve = 0;
|
||||||
const uint8_t *point_octets = NULL;
|
const uint8_t *point_octets = NULL;
|
||||||
size_t point_octets_len = 0;
|
size_t point_octets_len = 0;
|
||||||
const uint8_t *server_ecdh_params = NULL;
|
|
||||||
size_t server_ecdh_params_len = 0;
|
// 这部分是被签名的值,必须要拿到
|
||||||
uint16_t sig_alg;
|
const uint8_t *server_ecdh_params;
|
||||||
|
size_t server_ecdh_params_len;
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t *server_key_exchange;
|
||||||
|
size_t server_key_exchange_len;
|
||||||
|
int sig_alg;
|
||||||
const uint8_t *sig;
|
const uint8_t *sig;
|
||||||
size_t siglen;
|
size_t siglen;
|
||||||
|
|
||||||
@@ -2224,8 +1957,9 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0);
|
if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
if ((ret = tls12_record_get_handshake_server_key_exchange(conn->record,
|
if ((ret = tls_record_get_handshake_server_key_exchange(conn->record,
|
||||||
conn->cipher_suite, &server_ecdh_params, &server_ecdh_params_len,
|
TLS_server_key_exchange_ecdhe,
|
||||||
|
&server_ecdh_params, &server_ecdh_params_len,
|
||||||
&sig_alg, &sig, &siglen)) < 0) {
|
&sig_alg, &sig, &siglen)) < 0) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_decode_error);
|
tls_send_alert(conn, TLS_alert_decode_error);
|
||||||
@@ -2236,39 +1970,28 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tls_server_ecdh_params_from_bytes(&conn->key_exchange_group,
|
||||||
|
&server_key_exchange, &server_key_exchange_len,
|
||||||
|
&server_ecdh_params, &server_ecdh_params_len) != 1
|
||||||
|
|| tls_length_is_zero(server_ecdh_params_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (server_key_exchange_len > sizeof(conn->peer_key_exchange)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(conn->peer_key_exchange, server_key_exchange, server_key_exchange_len);
|
||||||
|
conn->peer_key_exchange_len = server_key_exchange_len;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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, "ServerKeyExchange", &conn->dgst_ctx);
|
if(conn->verbose) tls_handshake_digest_print(stderr, 0, 0, "ServerKeyExchange", &conn->dgst_ctx);
|
||||||
|
|
||||||
switch (conn->cipher_suite) {
|
|
||||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
|
||||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
|
||||||
#ifdef ENABLE_AES_CCM
|
|
||||||
case TLS_cipher_aes_128_ccm_sha256:
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
const uint8_t *p = server_ecdh_params;
|
|
||||||
size_t len = server_ecdh_params_len;
|
|
||||||
|
|
||||||
if (tls12_server_ecdh_params_from_bytes(&curve_type, &named_curve,
|
|
||||||
&point_octets, &point_octets_len, &p, &len) != 1
|
|
||||||
|| tls_length_is_zero(len) != 1) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_decode_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curve_type != TLS_curve_type_named_curve) {
|
if (curve_type != TLS_curve_type_named_curve) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_illegal_parameter);
|
tls_send_alert(conn, TLS_alert_illegal_parameter);
|
||||||
@@ -2384,7 +2107,7 @@ int tls_recv_server_key_exchange(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int tls_send_certificate_request(TLS_CONNECT *conn)
|
int tls12_send_certificate_request(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -2407,8 +2130,9 @@ int tls_send_certificate_request(TLS_CONNECT *conn)
|
|||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (tls_record_set_handshake_certificate_request(conn->record, &conn->recordlen,
|
if (tls12_record_set_handshake_certificate_request(conn->record, &conn->recordlen,
|
||||||
cert_types, sizeof(cert_types),
|
cert_types, sizeof(cert_types),
|
||||||
|
NULL, 0, // TODO: 这里需要至少添加TLS_cert_type_ecdsa_sign
|
||||||
ca_names, ca_names_len) != 1) {
|
ca_names, ca_names_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
@@ -2430,7 +2154,7 @@ int tls_send_certificate_request(TLS_CONNECT *conn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_recv_certificate_request(TLS_CONNECT *conn)
|
int tls12_recv_certificate_request(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t *record = conn->record;
|
uint8_t *record = conn->record;
|
||||||
@@ -2440,6 +2164,8 @@ int tls_recv_certificate_request(TLS_CONNECT *conn)
|
|||||||
|
|
||||||
const uint8_t *cert_types;
|
const uint8_t *cert_types;
|
||||||
size_t cert_types_len;
|
size_t cert_types_len;
|
||||||
|
const uint8_t *sig_algs;
|
||||||
|
size_t sig_algs_len;
|
||||||
const uint8_t *ca_names;
|
const uint8_t *ca_names;
|
||||||
size_t ca_names_len;
|
size_t ca_names_len;
|
||||||
|
|
||||||
@@ -2470,8 +2196,8 @@ int tls_recv_certificate_request(TLS_CONNECT *conn)
|
|||||||
if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0);
|
if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
if (tls_record_get_handshake_certificate_request(conn->record,
|
if (tls12_record_get_handshake_certificate_request(conn->record,
|
||||||
&cert_types, &cert_types_len, &ca_names, &ca_names_len) != 1) {
|
&cert_types, &cert_types_len, &sig_algs, &sig_algs_len, &ca_names, &ca_names_len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -2482,22 +2208,12 @@ int tls_recv_certificate_request(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 这里要检查一下服务器发送的,和本地的是否保持一致
|
if (tls_cert_types_has_ecdsa_sign(cert_types, cert_types_len) != 1
|
||||||
/*
|
|
||||||
if(!conn->client_certs_len) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tls_cert_types_accepted(cert_types, cert_types_len, conn->client_certs, conn->client_certs_len) != 1
|
|
||||||
|| tls_authorities_issued_certificate(ca_names, ca_names_len, conn->client_certs, conn->client_certs_len) != 1) {
|
|| 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);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
|
||||||
|
|
||||||
@@ -2656,203 +2372,6 @@ int tls_recv_client_certificate(TLS_CONNECT *conn)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tls12_generate_pre_master_secret(TLS_CONNECT *conn,
|
|
||||||
uint8_t *pre_master_secret, size_t *pre_master_secret_len)
|
|
||||||
{
|
|
||||||
if (!conn || !pre_master_secret || !pre_master_secret_len) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (*pre_master_secret_len != 32) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (conn->verbose >= 5) {
|
|
||||||
format_bytes(stderr, 0, 0, "pre_master_secret", pre_master_secret, *pre_master_secret_len);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tls12_generate_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) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tls_prf(conn->digest, pre_master_secret, 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);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tls12_generate_key_block(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
switch (conn->cipher_suite) {
|
|
||||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
|
||||||
#ifdef ENABLE_AES_CCM
|
|
||||||
case TLS_cipher_aes_128_ccm_sha256:
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
size_t keylen = conn->cipher->key_size;
|
|
||||||
size_t key_block_len = keylen * 2 + 8;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn->verbose >= 5) {
|
|
||||||
format_bytes(stderr, 0, 0, "key_blocks", conn->key_block, key_block_len);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TLS_cipher_ecdhe_sm4_cbc_sm3:
|
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
|
|
||||||
// OpenSSL tls1_prf 中,这里生成的是128字节,也就是把IV也生成了
|
|
||||||
// 为什么生成IV呢?
|
|
||||||
|
|
||||||
if (tls_prf(conn->digest, conn->master_secret, 48, "key expansion",
|
|
||||||
conn->server_random, 32,
|
|
||||||
conn->client_random, 32,
|
|
||||||
96, conn->key_block) != 1) {
|
|
||||||
error_print();
|
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
如果这里导出了IV,并且用这个IV去加密数据
|
|
||||||
被加密的数据中包含了一个随机的IV,那么这个随机的IV是干什么用的呢?
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (conn->verbose >= 5) {
|
|
||||||
format_bytes(stderr, 0, 0, "key_blocks", conn->key_block, 96);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tls12_generate_record_keys(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
switch (conn->cipher_suite) {
|
|
||||||
case TLS_cipher_ecdhe_sm4_gcm_sm3:
|
|
||||||
case TLS_cipher_ecdhe_ecdsa_with_aes_128_gcm_sha256:
|
|
||||||
#ifdef ENABLE_AES_CCM
|
|
||||||
case TLS_cipher_aes_128_ccm_sha256:
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
size_t keylen = conn->cipher->key_size;
|
|
||||||
|
|
||||||
if (conn->verbose >= 5) {
|
|
||||||
format_bytes(stderr, 0, 0, "client_write_key", conn->key_block, keylen);
|
|
||||||
format_bytes(stderr, 0, 0, "server_write_key", conn->key_block + keylen, keylen);
|
|
||||||
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 + keylen * 2 + 4, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (hmac_init(&conn->server_write_mac_ctx, conn->digest, conn->key_block + 32, 32) != 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (conn->is_client) {
|
|
||||||
block_cipher_set_encrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64);
|
|
||||||
block_cipher_set_decrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
block_cipher_set_decrypt_key(&conn->client_write_key, conn->cipher, conn->key_block + 64);
|
|
||||||
block_cipher_set_encrypt_key(&conn->server_write_key, conn->cipher, conn->key_block + 80);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tls_generate_keys(TLS_CONNECT *conn)
|
|
||||||
{
|
|
||||||
uint8_t pre_master_secret[32];
|
|
||||||
size_t pre_master_secret_len;
|
|
||||||
|
|
||||||
if (tls12_generate_pre_master_secret(conn, pre_master_secret, &pre_master_secret_len) != 1
|
|
||||||
|| tls12_generate_master_secret(conn, pre_master_secret, pre_master_secret_len) != 1
|
|
||||||
|| tls12_generate_key_block(conn) != 1
|
|
||||||
|| tls12_generate_record_keys(conn) != 1) {
|
|
||||||
error_print();
|
|
||||||
gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
tls_seq_num_reset(conn->client_seq_num);
|
|
||||||
tls_seq_num_reset(conn->server_seq_num);
|
|
||||||
|
|
||||||
/*
|
|
||||||
tls_secrets_print(stderr,
|
|
||||||
pre_master_secret, pre_master_secret_len,
|
|
||||||
conn->client_random, conn->server_random,
|
|
||||||
conn->master_secret,
|
|
||||||
conn->key_block, 96,
|
|
||||||
0, 4);
|
|
||||||
*/
|
|
||||||
|
|
||||||
gmssl_secure_clear(pre_master_secret, sizeof(pre_master_secret));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int tls_send_client_key_exchange(TLS_CONNECT *conn)
|
int tls_send_client_key_exchange(TLS_CONNECT *conn)
|
||||||
{
|
{
|
||||||
@@ -2884,7 +2403,7 @@ int tls_send_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(conn->verbose) tls_trace("send ClientKeyExchange\n");
|
if(conn->verbose) tls_trace("send ClientKeyExchange\n");
|
||||||
if (tls_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, len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_internal_error);
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
@@ -2937,7 +2456,7 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0);
|
if(conn->verbose) tls12_record_trace(stderr, conn->record, conn->recordlen, 0, 0);
|
||||||
|
|
||||||
if (tls_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) {
|
||||||
error_print();
|
error_print();
|
||||||
tls_send_alert(conn, TLS_alert_unexpected_message);
|
tls_send_alert(conn, TLS_alert_unexpected_message);
|
||||||
@@ -3458,7 +2977,7 @@ int tls12_do_client_handshake(TLS_CONNECT *conn)
|
|||||||
if(conn->verbose) {
|
if(conn->verbose) {
|
||||||
fprintf(stderr, "TLS_state_certificate_request\n");
|
fprintf(stderr, "TLS_state_certificate_request\n");
|
||||||
}
|
}
|
||||||
ret = tls_recv_certificate_request(conn);
|
ret = tls12_recv_certificate_request(conn);
|
||||||
if(conn->verbose) {
|
if(conn->verbose) {
|
||||||
fprintf(stderr, " ret = %d\n", ret);
|
fprintf(stderr, " ret = %d\n", ret);
|
||||||
}
|
}
|
||||||
@@ -3567,7 +3086,7 @@ int tls12_do_server_handshake(TLS_CONNECT *conn)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TLS_state_certificate_request:
|
case TLS_state_certificate_request:
|
||||||
ret = tls_send_certificate_request(conn);
|
ret = tls12_send_certificate_request(conn);
|
||||||
next_state = TLS_state_server_hello_done;
|
next_state = TLS_state_server_hello_done;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
587
src/tls_cert.c
Normal file
587
src/tls_cert.c
Normal file
@@ -0,0 +1,587 @@
|
|||||||
|
/*
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <gmssl/rand.h>
|
||||||
|
#include <gmssl/x509.h>
|
||||||
|
#include <gmssl/error.h>
|
||||||
|
#include <gmssl/endian.h>
|
||||||
|
#include <gmssl/mem.h>
|
||||||
|
#include <gmssl/sm2.h>
|
||||||
|
#include <gmssl/sm3.h>
|
||||||
|
#include <gmssl/sm4.h>
|
||||||
|
#include <gmssl/pem.h>
|
||||||
|
#include <gmssl/tls.h>
|
||||||
|
|
||||||
|
|
||||||
|
static int tls_cert_issuer_match_subject(const uint8_t *cert, size_t certlen,
|
||||||
|
const uint8_t *issuer_cert, size_t issuer_certlen)
|
||||||
|
{
|
||||||
|
const uint8_t *issuer;
|
||||||
|
size_t issuer_len;
|
||||||
|
const uint8_t *subject;
|
||||||
|
size_t subject_len;
|
||||||
|
|
||||||
|
if (x509_cert_get_issuer(cert, certlen, &issuer, &issuer_len) != 1
|
||||||
|
|| x509_cert_get_subject(issuer_cert, issuer_certlen, &subject, &subject_len) != 1
|
||||||
|
|| x509_name_equ(issuer, issuer_len, subject, subject_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tls_cert_chain_check_order(const uint8_t *certs, size_t certslen)
|
||||||
|
{
|
||||||
|
const uint8_t *cert;
|
||||||
|
size_t certlen;
|
||||||
|
|
||||||
|
if (!certs || !certslen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (certslen) {
|
||||||
|
const uint8_t *issuer_cert;
|
||||||
|
size_t issuer_certlen;
|
||||||
|
|
||||||
|
if (x509_cert_from_der(&issuer_cert, &issuer_certlen, &certs, &certslen) != 1
|
||||||
|
|| tls_cert_issuer_match_subject(cert, certlen, issuer_cert, issuer_certlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cert = issuer_cert;
|
||||||
|
certlen = issuer_certlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tlcp_cert_chain_check_order(const uint8_t *certs, size_t certslen)
|
||||||
|
{
|
||||||
|
const uint8_t *sign_cert;
|
||||||
|
size_t sign_certlen;
|
||||||
|
const uint8_t *enc_cert;
|
||||||
|
size_t enc_certlen;
|
||||||
|
const uint8_t *ca_cert;
|
||||||
|
size_t ca_certlen;
|
||||||
|
|
||||||
|
if (!certs || !certslen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (x509_cert_from_der(&sign_cert, &sign_certlen, &certs, &certslen) != 1
|
||||||
|
|| x509_cert_from_der(&enc_cert, &enc_certlen, &certs, &certslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!certslen) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x509_cert_from_der(&ca_cert, &ca_certlen, &certs, &certslen) != 1
|
||||||
|
|| tls_cert_issuer_match_subject(sign_cert, sign_certlen, ca_cert, ca_certlen) != 1
|
||||||
|
|| tls_cert_issuer_match_subject(enc_cert, enc_certlen, ca_cert, ca_certlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (certslen) {
|
||||||
|
const uint8_t *issuer_cert;
|
||||||
|
size_t issuer_certlen;
|
||||||
|
|
||||||
|
if (x509_cert_from_der(&issuer_cert, &issuer_certlen, &certs, &certslen) != 1
|
||||||
|
|| tls_cert_issuer_match_subject(ca_cert, ca_certlen, issuer_cert, issuer_certlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ca_cert = issuer_cert;
|
||||||
|
ca_certlen = issuer_certlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
size_t cert_chain_len;
|
||||||
|
uint8_t *certs;
|
||||||
|
size_t certslen;
|
||||||
|
FILE *certfp = NULL;
|
||||||
|
const uint8_t *cert;
|
||||||
|
size_t certlen;
|
||||||
|
X509_KEY public_key;
|
||||||
|
size_t key_idx;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
if (!(certfp = fopen(chainfile, "r"))) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cert_chain = ctx->cert_chains + ctx->cert_chains_len ;
|
||||||
|
certs = cert_chain + tls_uint24_size();
|
||||||
|
if (x509_certs_from_pem(certs, &certslen,
|
||||||
|
sizeof(ctx->cert_chains) - ctx->cert_chains_len - tls_uint24_size(), certfp) != 1) {
|
||||||
|
fclose(certfp);
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_cert_chain_check_order(certs, certslen) != 1) {
|
||||||
|
fclose(certfp);
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add private key to ctx->x509_keys
|
||||||
|
if (sizeof(ctx->x509_keys)/sizeof(ctx->x509_keys[0]) <= ctx->x509_keys_cnt) {
|
||||||
|
fclose(certfp);
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
key_idx = ctx->x509_keys_cnt;
|
||||||
|
if (x509_certs_get_cert_by_index(certs, certslen, 0, &cert, &certlen) != 1
|
||||||
|
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
|
||||||
|
fclose(certfp);
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (public_key.algor == OID_ec_public_key) {
|
||||||
|
if (!(keyfp = fopen(keyfile, "r"))) {
|
||||||
|
fclose(certfp);
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!(keyfp = fopen(keyfile, "rb+"))) {
|
||||||
|
fclose(certfp);
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x509_private_key_from_file(&ctx->x509_keys[key_idx], public_key.algor, keypass, keyfp) != 1) {
|
||||||
|
fclose(certfp);
|
||||||
|
fclose(keyfp);
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (x509_public_key_equ(&ctx->x509_keys[key_idx], &public_key) != 1) {
|
||||||
|
x509_key_cleanup(&ctx->x509_keys[key_idx]);
|
||||||
|
fclose(certfp);
|
||||||
|
fclose(keyfp);
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cert_chain_len = 0;
|
||||||
|
tls_uint24_to_bytes((uint24_t)certslen, &cert_chain, &cert_chain_len);
|
||||||
|
cert_chain_len += certslen;
|
||||||
|
ctx->cert_chains_len += cert_chain_len;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (!ctx || !chainfile || !keyfile || !keypass) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!tls_protocol_name(ctx->protocol)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ctx->cert_chains_len || ctx->x509_keys_cnt) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_ctx_add_certificate_chain_and_key(ctx, chainfile, keyfile, keypass) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tlcp_ctx_add_server_certificate_and_keys(TLS_CTX *ctx, const char *chainfile,
|
||||||
|
const char *keyfile, const char *keypass)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
const int algor = OID_ec_public_key;
|
||||||
|
const int algor_param = OID_sm2;
|
||||||
|
uint8_t *cert_chain;
|
||||||
|
uint8_t *certs;
|
||||||
|
size_t certslen;
|
||||||
|
size_t cert_chains_len;
|
||||||
|
size_t key_idx;
|
||||||
|
FILE *certfp = NULL;
|
||||||
|
FILE *keyfp = NULL;
|
||||||
|
|
||||||
|
const uint8_t *cert;
|
||||||
|
size_t certlen;
|
||||||
|
X509_KEY public_key;
|
||||||
|
|
||||||
|
|
||||||
|
if (!ctx || !chainfile || !keyfile || !keypass) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!tls_protocol_name(ctx->protocol)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ctx->protocol != TLS_protocol_tlcp || ctx->is_client) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ctx->x509_keys_cnt >= sizeof(ctx->x509_keys)/sizeof(ctx->x509_keys[0])) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
key_idx = ctx->x509_keys_cnt;
|
||||||
|
|
||||||
|
if (sizeof(ctx->cert_chains) <= ctx->cert_chains_len + tls_uint24_size()) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!(certfp = fopen(chainfile, "r"))) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
cert_chain = ctx->cert_chains + ctx->cert_chains_len;
|
||||||
|
certs = cert_chain + tls_uint24_size();
|
||||||
|
if (x509_certs_from_pem(certs, &certslen,
|
||||||
|
sizeof(ctx->cert_chains) - ctx->cert_chains_len - tls_uint24_size(), certfp) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (tlcp_cert_chain_check_order(certs, certslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
cert_chains_len = 0;
|
||||||
|
tls_uint24_to_bytes((uint24_t)certslen, &cert_chain, &cert_chains_len);
|
||||||
|
cert_chains_len += certslen;
|
||||||
|
|
||||||
|
// load sign key
|
||||||
|
if (!(keyfp = fopen(keyfile, "r"))) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (x509_private_key_from_file(&ctx->x509_keys[key_idx], algor, keypass, keyfp) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (x509_certs_get_cert_by_index(certs, certslen, 0, &cert, &certlen) != 1
|
||||||
|
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (public_key.algor != algor || public_key.algor_param != algor_param
|
||||||
|
|| x509_public_key_equ(&ctx->x509_keys[key_idx], &public_key) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load enc key
|
||||||
|
if (x509_private_key_from_file(&ctx->enc_keys[key_idx], algor, keypass, keyfp) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (x509_certs_get_cert_by_index(certs, certslen, 1, &cert, &certlen) != 1
|
||||||
|
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (public_key.algor != algor || public_key.algor_param != algor_param
|
||||||
|
|| x509_public_key_equ(&ctx->enc_keys[key_idx], &public_key) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->cert_chains_len += cert_chains_len;
|
||||||
|
ctx->x509_keys_cnt++;
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (ret != 1) {
|
||||||
|
x509_key_cleanup(&ctx->x509_keys[key_idx]);
|
||||||
|
x509_key_cleanup(&ctx->enc_keys[key_idx]);
|
||||||
|
}
|
||||||
|
if (certfp) fclose(certfp);
|
||||||
|
if (keyfp) fclose(keyfp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chainfile,
|
||||||
|
const char *keyfile, const char *keypass)
|
||||||
|
{
|
||||||
|
if (!ctx || ctx->cert_chains_len || ctx->x509_keys_cnt) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tlcp_ctx_add_server_certificate_and_keys(ctx, chainfile,
|
||||||
|
keyfile, keypass) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_authorities_issued_certificate(const uint8_t *ca_names, size_t ca_names_len, const uint8_t *certs, size_t certslen)
|
||||||
|
{
|
||||||
|
const uint8_t *cert;
|
||||||
|
size_t certlen;
|
||||||
|
const uint8_t *issuer;
|
||||||
|
size_t issuer_len;
|
||||||
|
|
||||||
|
|
||||||
|
//x509_certs_print(stderr, 0, 0, "cert_chain", certs, certslen);
|
||||||
|
|
||||||
|
|
||||||
|
if (x509_certs_get_last(certs, certslen, &cert, &certlen) != 1
|
||||||
|
|| x509_cert_get_issuer(cert, certlen, &issuer, &issuer_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//x509_cert_print(stderr, 0, 0, "last cert", cert, certlen);
|
||||||
|
|
||||||
|
//x509_name_print(stderr, 0, 0, "issuer", issuer, issuer_len);
|
||||||
|
|
||||||
|
while (ca_names_len) {
|
||||||
|
const uint8_t *p;
|
||||||
|
size_t len;
|
||||||
|
const uint8_t *name;
|
||||||
|
size_t namelen;
|
||||||
|
|
||||||
|
if (tls_uint16array_from_bytes(&p, &len, &ca_names, &ca_names_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asn1_sequence_from_der(&name, &namelen, &p, &len) != 1
|
||||||
|
|| asn1_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//x509_name_print(stderr, 0, 0, "ca", name, namelen);
|
||||||
|
|
||||||
|
|
||||||
|
if (x509_name_equ(name, namelen, issuer, issuer_len) == 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error_print();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_cert_types_has_ecdsa_sign(const uint8_t *types, size_t types_len)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这个函数不是很好,直接提供的是一个文件名
|
||||||
|
int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth)
|
||||||
|
{
|
||||||
|
if (!ctx || !cacertsfile) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (depth < 0 || depth > TLS_MAX_VERIFY_DEPTH) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!tls_protocol_name(ctx->protocol)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ctx->cacerts) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (x509_certs_new_from_file(&ctx->cacerts, &ctx->cacertslen, cacertsfile) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ctx->cacertslen == 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在读取CA证书的时候,提取了证书的名字
|
||||||
|
if (tls_authorities_from_certs(ctx->ca_names, &ctx->ca_names_len, sizeof(ctx->ca_names),
|
||||||
|
ctx->cacerts, ctx->cacertslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_trusted_authorities_from_ca_names(ctx->trusted_authorities, &ctx->trusted_authorities_len,
|
||||||
|
sizeof(ctx->trusted_authorities), ctx->ca_names, ctx->ca_names_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->verify_depth = depth;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_authorities_from_certs(uint8_t *names, size_t *nameslen, size_t maxlen, const uint8_t *certs, size_t certslen)
|
||||||
|
{
|
||||||
|
const uint8_t *cert;
|
||||||
|
size_t certlen;
|
||||||
|
const uint8_t *name;
|
||||||
|
size_t namelen;
|
||||||
|
|
||||||
|
*nameslen = 0;
|
||||||
|
while (certslen) {
|
||||||
|
size_t alen = 0;
|
||||||
|
if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1
|
||||||
|
|| x509_cert_get_subject(cert, certlen, &name, &namelen) != 1
|
||||||
|
|| asn1_sequence_to_der(name, namelen, NULL, &alen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_uint16_size() + alen > maxlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (alen > UINT16_MAX) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tls_uint16_to_bytes((uint16_t)alen, &names, nameslen);
|
||||||
|
maxlen -= tls_uint16_size();
|
||||||
|
|
||||||
|
if (asn1_sequence_to_der(name, namelen, &names, nameslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
maxlen -= alen;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int tls12_cert_chains_select(const uint8_t *cert_chains, size_t cert_chains_len,
|
||||||
|
const int *supported_groups, size_t supported_groups_cnt, // optional
|
||||||
|
const int *signature_algorithms, size_t signature_algorithms_cnt, // optional
|
||||||
|
const uint8_t *ca_names, size_t ca_names_len, // certificate_authorities optional
|
||||||
|
const uint8_t *host_name, size_t host_name_len, // optional, only in ClientHello
|
||||||
|
const uint8_t **certs, size_t *certs_len, size_t *certs_idx, int *prefered_sig_alg) // optional
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!cert_chains || !cert_chains_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; cert_chains_len; i++) {
|
||||||
|
const uint8_t *cert_chain;
|
||||||
|
size_t cert_chain_len;
|
||||||
|
int sig_alg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (tls_uint24array_from_bytes(&cert_chain, &cert_chain_len,
|
||||||
|
&cert_chains, &cert_chains_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (certs) *certs = cert_chain;
|
||||||
|
if (certs_len) *certs_len = cert_chain_len;
|
||||||
|
if (certs_idx) *certs_idx = i;
|
||||||
|
if (prefered_sig_alg) *prefered_sig_alg = sig_alg;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -537,6 +537,48 @@ int tls13_session_print(FILE *fp, int fmt, int ind, const char *label, const uin
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tls_uint16array_from_file(uint8_t *arr, size_t *arrlen, size_t maxlen, FILE *fp)
|
||||||
|
{
|
||||||
|
uint16_t datalen;
|
||||||
|
const uint8_t *cp;
|
||||||
|
size_t len = 2;
|
||||||
|
|
||||||
|
if (!arr || !arrlen || !fp) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (maxlen < 2) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fread(arr, 1, 2, fp) != 2) {
|
||||||
|
if (feof(fp)) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cp = arr;
|
||||||
|
len = 2;
|
||||||
|
if (tls_uint16_from_bytes(&datalen, &cp, &len) != 1
|
||||||
|
|| tls_length_is_zero(len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*arrlen = 2 + datalen;
|
||||||
|
if ((size_t)datalen + 2 > maxlen) {
|
||||||
|
error_print();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (fread(arr + 2, 1, datalen, fp) != datalen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// 需要检查一下加入的SESSION的cipher_suite是否和conn的匹配
|
// 需要检查一下加入的SESSION的cipher_suite是否和conn的匹配
|
||||||
|
|
||||||
// client only
|
// client only
|
||||||
|
|||||||
@@ -1242,3 +1242,47 @@ int tls_encrypted_record_print(FILE *fp, const uint8_t *record, size_t recordle
|
|||||||
fprintf(fp, "\n");
|
fprintf(fp, "\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tls_key_exchange_modes_print(FILE *fp, int fmt, int ind, const char *label, int modes)
|
||||||
|
{
|
||||||
|
int first = 1;
|
||||||
|
|
||||||
|
format_print(fp, fmt, ind, "%s:", label);
|
||||||
|
|
||||||
|
if (modes & TLS_KE_CERT_DHE) {
|
||||||
|
fprintf(fp, " CERT_DHE");
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
if (modes & TLS_KE_PSK_DHE) {
|
||||||
|
if (first)
|
||||||
|
fprintf(fp, " PSK_DHE");
|
||||||
|
else fprintf(fp, "|PSK_DHE");
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
if (modes & TLS_KE_PSK) {
|
||||||
|
if (first)
|
||||||
|
fprintf(fp, " PSK");
|
||||||
|
else fprintf(fp, "|PSK");
|
||||||
|
}
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_handshake_digest_print(FILE *fp, int fmt, int ind, const char *label, const DIGEST_CTX *dgst_ctx)
|
||||||
|
{
|
||||||
|
DIGEST_CTX tmp_ctx;
|
||||||
|
uint8_t dgst[64];
|
||||||
|
size_t dgstlen;
|
||||||
|
|
||||||
|
tmp_ctx = *dgst_ctx;
|
||||||
|
|
||||||
|
if (digest_finish(&tmp_ctx, dgst, &dgstlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
format_print(fp, fmt, ind, "transcript_hash ");
|
||||||
|
format_bytes(fp, 0, 0, label, dgst, dgstlen);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user