Update TLS 1.3

This commit is contained in:
Zhi Guan
2026-04-12 11:48:15 +08:00
parent 3d29d5066d
commit 2e550edc35
16 changed files with 4590 additions and 1992 deletions

View File

@@ -150,6 +150,7 @@ int tlcp_server_key_exchange_pke_print(FILE *fp, const uint8_t *data, size_t dat
return 1;
}
#if 0
int _tlcp_do_connect(TLS_CONNECT *conn)
{
int ret = -1;
@@ -1056,6 +1057,7 @@ end:
return ret;
}
#endif
/*
SM9_SM4_CBC_SM3

488
src/tls.c
View File

@@ -18,6 +18,7 @@
#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>
@@ -64,6 +65,14 @@ void tls_uint32_to_bytes(uint32_t a, uint8_t **out, size_t *outlen)
(*outlen) += 4;
}
void tls_uint64_to_bytes(uint64_t a, uint8_t **out, size_t *outlen)
{
if (out && *out) {
PUTU64(*out, a);
}
(*outlen) += 8;
}
void tls_array_to_bytes(const uint8_t *data, size_t datalen, uint8_t **out, size_t *outlen)
{
if (out && *out) {
@@ -156,6 +165,18 @@ int tls_uint32_from_bytes(uint32_t *a, const uint8_t **in, size_t *inlen)
return 1;
}
int tls_uint64_from_bytes(uint64_t *a, const uint8_t **in, size_t *inlen)
{
if (*inlen < 8) {
error_print();
return -1;
}
*a = GETU64(*in);
*in += 8;
*inlen -= 8;
return 1;
}
int tls_array_from_bytes(const uint8_t **data, size_t datalen, const uint8_t **in, size_t *inlen)
{
if (*inlen < datalen) {
@@ -1466,11 +1487,11 @@ int tls_record_get_application_data(uint8_t *record,
return 1;
}
int tls_type_is_in_list(int cipher, const int *list, size_t list_count)
int tls_type_is_in_list(int type, const int *list, size_t list_count)
{
size_t i;
for (i = 0; i < list_count; i++) {
if (cipher == list[i]) {
if (type == list[i]) {
return 1;
}
}
@@ -2162,10 +2183,78 @@ void tls_ctx_cleanup(TLS_CTX *ctx)
}
}
int tls_ctx_print(FILE *fp, int fmt, int ind, const char *label, const TLS_CTX *ctx)
{
return 0;
}
int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client)
{
const int supported_versions[] = {
TLS_protocol_tls13,
TLS_protocol_tls12,
TLS_protocol_tlcp,
};
if (!ctx) {
error_print();
return -1;
}
memset(ctx, 0, sizeof(*ctx));
// protocol
switch (protocol) {
case TLS_protocol_tlcp:
case TLS_protocol_tls12:
case TLS_protocol_tls13:
ctx->protocol = protocol;
break;
default:
error_print();
return -1;
}
ctx->is_client = is_client ? 1 : 0;
// supported_versions
memcpy(ctx->supported_versions, supported_versions, sizeof(supported_versions));
ctx->supported_versions_cnt = sizeof(supported_versions)/sizeof(supported_versions[0]);
// key_exchange_modes
ctx->key_exchange_modes = TLS_KE_CERT_DHE;
ctx->verify_depth = 5;
// key_share
ctx->key_exchanges_cnt = 2;
return 1;
}
int tls_ctx_set_supported_versions(TLS_CTX *ctx, const int *versions, size_t versions_cnt)
{
size_t i;
@@ -2178,6 +2267,7 @@ int tls_ctx_set_supported_versions(TLS_CTX *ctx, const int *versions, size_t ver
error_print();
return -1;
}
for (i = 0; i < versions_cnt; i++) {
switch (versions[i]) {
case TLS_protocol_tls13:
@@ -2191,130 +2281,10 @@ int tls_ctx_set_supported_versions(TLS_CTX *ctx, const int *versions, size_t ver
ctx->supported_versions[i] = versions[i];
}
ctx->supported_versions_cnt = versions_cnt;
return 1;
}
int tls_ctx_set_supported_groups(TLS_CTX *ctx, const int *groups, size_t groups_cnt)
{
size_t i;
if (!ctx || !groups || !groups_cnt) {
error_print();
return -1;
}
if (groups_cnt > sizeof(ctx->supported_groups)/sizeof(ctx->supported_groups[0])) {
error_print();
return -1;
}
for (i = 0; i < groups_cnt; i++) {
switch (groups[i]) {
case TLS_curve_sm2p256v1:
case TLS_curve_secp256r1:
break;
default:
error_print();
return -1;
}
ctx->supported_groups[i] = groups[i];
}
ctx->supported_groups_cnt = groups_cnt;
return 1;
}
int tls_ctx_set_signature_algorithms(TLS_CTX *ctx, const int *sig_algs, size_t sig_algs_cnt)
{
size_t i;
if (!ctx || !sig_algs || !sig_algs_cnt) {
error_print();
return -1;
}
if (sig_algs_cnt > sizeof(ctx->signature_algorithms)/sizeof(ctx->signature_algorithms[0])) {
error_print();
return -1;
}
for (i = 0; i < sig_algs_cnt; i++) {
switch (sig_algs[i]) {
case TLS_sig_sm2sig_sm3:
case TLS_sig_ecdsa_secp256r1_sha256:
break;
default:
error_print();
return -1;
}
ctx->signature_algorithms[i] = sig_algs[i];
}
ctx->signature_algorithms_cnt = sig_algs_cnt;
return 1;
}
int tls_ctx_init(TLS_CTX *ctx, int protocol, int is_client)
{
const int supported_versions[] = {
TLS_protocol_tls13,
TLS_protocol_tls12,
TLS_protocol_tlcp,
};
size_t supported_versions_cnt = sizeof(supported_versions)/sizeof(supported_versions[0]);
const int supported_groups[] = {
TLS_curve_sm2p256v1,
TLS_curve_secp256r1,
};
size_t supported_groups_cnt = sizeof(supported_groups)/sizeof(supported_groups[0]);
const int signature_algorithms[] = {
TLS_sig_sm2sig_sm3,
TLS_sig_ecdsa_secp256r1_sha256,
};
size_t signature_algorithms_cnt = sizeof(signature_algorithms)/sizeof(signature_algorithms[0]);
if (!ctx) {
error_print();
return -1;
}
memset(ctx, 0, sizeof(*ctx));
switch (protocol) {
case TLS_protocol_tlcp:
case TLS_protocol_tls12:
case TLS_protocol_tls13:
ctx->protocol = protocol;
break;
default:
error_print();
return -1;
}
ctx->is_client = is_client ? 1 : 0;
if (tls_ctx_set_supported_versions(ctx, supported_versions, supported_versions_cnt) != 1
|| tls_ctx_set_supported_groups(ctx, supported_groups, supported_groups_cnt) != 1
|| tls_ctx_set_signature_algorithms(ctx, signature_algorithms, signature_algorithms_cnt) != 1) {
error_print();
return -1;
}
// test HelloRetryRequest
if (!is_client) {
tls_ctx_set_supported_groups(ctx, supported_groups + 1, supported_groups_cnt - 1);
}
ctx->verify_depth = 5;
// TODO: 需要通过函数或者其他设置来启用这个开关
ctx->pre_shared_key_enabled = 1;
return 1;
}
int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cipher_suites_cnt)
{
size_t i;
@@ -2323,7 +2293,7 @@ int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cip
error_print();
return -1;
}
if (cipher_suites_cnt < 1 || cipher_suites_cnt > TLS_MAX_CIPHER_SUITES_COUNT) {
if (cipher_suites_cnt > sizeof(ctx->cipher_suites)/sizeof(ctx->cipher_suites[0])) {
error_print();
return -1;
}
@@ -2333,18 +2303,30 @@ int tls_ctx_set_cipher_suites(TLS_CTX *ctx, const int *cipher_suites, size_t cip
error_print();
return -1;
}
}
for (i = 0; i < cipher_suites_cnt; i++) {
if (!tls_cipher_suite_support_protocol(cipher_suites[i], ctx->protocol)) {
error_print();
return -1;
}
ctx->cipher_suites[i] = cipher_suites[i];
}
ctx->cipher_suites_cnt = cipher_suites_cnt;
return 1;
}
int tls_ctx_set_key_exchange_modes(TLS_CTX *ctx, int modes)
{
if (!ctx) {
error_print();
return -1;
}
if (modes & ~(TLS_KE_CERT_DHE|TLS_KE_PSK_DHE|TLS_KE_PSK)) {
error_print();
return -1;
}
ctx->key_exchange_modes = modes;
return 1;
}
// 这个函数不是很好,直接提供的是一个文件名
int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth)
{
if (!ctx || !cacertsfile) {
@@ -2377,7 +2359,89 @@ int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth
}
// 这个函数要独立出去
// 这个函数需要设置一个默认的证书链
// 这个函数实际上是有问题的没有给这个证书链提供status_request和sct_list
// cert_chain的格式到底是什么呢
// 是单独的证书链,还是也包含扩展呢?
int tls_ctx_add_certificate_chain_and_key(TLS_CTX *ctx, const char *chainfile,
const char *keyfile, const char *keypass)
{
uint8_t *cert_chain;
size_t cert_chain_len;
FILE *certfp = NULL;
const uint8_t *cert;
size_t certlen;
X509_KEY public_key;
FILE *keyfp = NULL;
if (!ctx || !chainfile || !keyfile || !keypass) {
error_print();
return -1;
}
// no space in ctx->cert_chains[]
if (sizeof(ctx->cert_chains) <= ctx->cert_chains_len + tls_uint24_size()) {
error_print();
return -1;
}
// no space in ctx->x509_keys[]
if (sizeof(ctx->x509_keys)/sizeof(ctx->x509_keys[0]) <= ctx->x509_keys_cnt) {
error_print();
return -1;
}
if (!(certfp = fopen(chainfile, "r"))) {
error_print();
return -1;
}
// read and save cert_chain as uint24array
cert_chain = ctx->cert_chains + ctx->cert_chains_len;
if (x509_certs_from_pem(cert_chain + tls_uint24_size(), &cert_chain_len,
sizeof(ctx->cert_chains) - ctx->cert_chains_len - tls_uint24_size(),
certfp) != 1) {
error_print();
return -1;
}
tls_uint24_to_bytes(cert_chain_len, &cert_chain, &cert_chain_len);
ctx->cert_chains_len += cert_chain_len;
cert_chain_len -= tls_uint24_size();
if (x509_certs_get_cert_by_index(cert_chain, cert_chain_len, 0, &cert, &certlen) != 1
|| x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
fclose(certfp);
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;
}
}
// read and save at most two keys as uint16array
if (x509_private_key_from_file(&ctx->x509_keys[ctx->x509_keys_cnt], public_key.algor, keypass, keyfp) != 1) {
fclose(certfp);
fclose(keyfp);
error_print();
return -1;
}
ctx->x509_keys_cnt++;
fclose(certfp);
fclose(keyfp);
return 1;
}
// 保留这个函数,相当于是对证书链的初始化
int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile,
const char *keyfile, const char *keypass)
{
@@ -2428,10 +2492,6 @@ int tls_ctx_set_certificate_and_key(TLS_CTX *ctx, const char *chainfile,
error_print();
return -1;
}
if (x509_public_key_equ(&ctx->signkey, &public_key) != 1) {
error_print();
goto end;
}
ctx->certs = certs;
ctx->certslen = certslen;
@@ -2444,7 +2504,6 @@ end:
return ret;
}
int tls_ctx_set_tlcp_server_certificate_and_keys(TLS_CTX *ctx, const char *chainfile,
const char *signkeyfile, const char *signkeypass,
const char *kenckeyfile, const char *kenckeypass)
@@ -2533,71 +2592,88 @@ end:
return ret;
}
/*
服务器的控制开关
int tls_ctx_set_supported_groups(TLS_CTX *ctx, const int *groups, size_t groups_cnt)
{
size_t i;
* 是否验证客户端,这可能依赖很多条件
服务器至少需要提供CA证书
状态certificate_request = on
if (!ctx || !groups || !groups_cnt) {
error_print();
return -1;
}
if (groups_cnt > sizeof(ctx->supported_groups)/sizeof(ctx->supported_groups[0])) {
error_print();
return -1;
}
* 是否发送NewSessionTicket
这和是否采用PSK模式实际上是没有关系的
本次启动服务器可能不支持PSK模式但是仍然可以提供session_ticket
服务器需要设置session的加密密钥
for (i = 0; i < groups_cnt; i++) {
switch (groups[i]) {
case TLS_curve_sm2p256v1:
case TLS_curve_secp256r1:
break;
default:
error_print();
return -1;
}
ctx->supported_groups[i] = groups[i];
}
ctx->supported_groups_cnt = groups_cnt;
是否要设置可以发送ticket的次数
以及ticket有关的信息有效期之类
自动化设置max_early_data_size
* 是否支持pre_shared_key (1-RTT)
TLS 1.3有好几种PSK的模式比如PSK之后是否进行ECDH
服务器需要设置session的加密密钥
// ok
* 是否支持early_data
这是一个独立的开关
return 1;
}
客户端的控制开关
* 初始设置客户端的证书(这和服务器无关)
int tls_ctx_set_signature_algorithms(TLS_CTX *ctx, const int *sig_algs, size_t sig_algs_cnt)
{
size_t i;
* 是否发送pre_shared_key
if (!ctx || !sig_algs || !sig_algs_cnt) {
error_print();
return -1;
}
if (sig_algs_cnt > sizeof(ctx->signature_algorithms)/sizeof(ctx->signature_algorithms[0])) {
error_print();
return -1;
}
需要提供session_ticket的文件载入信息
并且需要开关
for (i = 0; i < sig_algs_cnt; i++) {
switch (sig_algs[i]) {
case TLS_sig_sm2sig_sm3:
case TLS_sig_ecdsa_secp256r1_sha256:
break;
default:
error_print();
return -1;
}
ctx->signature_algorithms[i] = sig_algs[i];
}
ctx->signature_algorithms_cnt = sig_algs_cnt;
* 是否发送early_data
return 1;
}
是否已经准备了session
是否已经准备了early_data数据这个无所谓只要指定了这个状态有没有数据都发送一个early_data报文
如果有max_early_data_size要判断一下大小
int tls13_ctx_set_client_hello_key_exchanges_cnt(TLS_CTX *ctx, size_t cnt)
{
if (!ctx) {
error_print();
return -1;
}
if (cnt > sizeof(((TLS_CONNECT *)NULL)->key_exchanges)/sizeof(((TLS_CONNECT *)NULL)->key_exchanges[0])) {
error_print();
return -1;
}
我们可以延迟到开始发送early_data的时候再检查
ctx->key_exchanges_cnt = cnt;
return 1;
}
服务器是否支持PSK客户端是否发送PSK实际上是两个独立的功能。
如果我们打开服务器支持PSK的开关但是没有设置session_ticket的密钥那么就会出问题
我们还是延迟检查比较好
因为PSK对于服务器来说是一个隐含的不是主动的服务器是被动的
如果服务器准备好了session_ticket_key那么就意味着允许
对于客户端来说如果要在ClientHello中提供pre_shared_key那么就必须要提供session_infile
或者说set_session_in 就说明我们一定是要发送pre_shared_key的并且就来自于session_in
但是如果设置了session_out 那么意味着我们会保存信息但是不一定会发送psk这两个是独立的
因此对于客户端来说pre_shared_key的状态是否有必要的
*/
int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx)
int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx)
{
size_t i;
memset(conn, 0, sizeof(*conn));
@@ -2607,10 +2683,12 @@ int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx)
conn->protocol = ctx->protocol;
/*
for (i = 0; i < ctx->cipher_suites_cnt; i++) {
conn->cipher_suites[i] = ctx->cipher_suites[i];
}
conn->cipher_suites_cnt = ctx->cipher_suites_cnt;
*/
if (ctx->certslen > TLS_MAX_CERTIFICATES_SIZE) {
@@ -2625,12 +2703,15 @@ int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx)
conn->server_certs_len = ctx->certslen;
}
/*
if (ctx->cacertslen > TLS_MAX_CERTIFICATES_SIZE) {
error_print();
return -1;
}
memcpy(conn->ca_certs, ctx->cacerts, ctx->cacertslen);
conn->ca_certs_len = ctx->cacertslen;
*/
conn->sign_key = ctx->signkey;
conn->kenc_key = ctx->kenckey;
@@ -2638,23 +2719,22 @@ int tls_init(TLS_CONNECT *conn, const TLS_CTX *ctx)
conn->quiet = ctx->quiet;
conn->verify_depth = ctx->verify_depth;
conn->ctx = ctx;
conn->key_exchanges_cnt = 2;
conn->key_exchanges_cnt = ctx->key_exchanges_cnt;
conn->new_session_ticket = ctx->new_session_ticket;
conn->pre_shared_key_enabled = ctx->pre_shared_key_enabled;
// 仅仅用于测试0-RTT
/*
conn->early_data_enabled = 1;
tls13_set_early_data(conn, (uint8_t *)"Early data", strlen("Early data"));
*/
conn->key_exchange_modes = ctx->key_exchange_modes;
tls13_set_max_early_data_size(conn, ctx->max_early_data_size);
// early_data
conn->early_data = ctx->early_data;
conn->max_early_data_size = ctx->max_early_data_size;
return 1;
@@ -2665,6 +2745,7 @@ void tls_cleanup(TLS_CONNECT *conn)
gmssl_secure_clear(conn, sizeof(TLS_CONNECT));
}
/*
int tls_set_hostname(TLS_CONNECT *conn, const char *hostname)
{
if (strlen(hostname) > 255) {
@@ -2674,6 +2755,7 @@ int tls_set_hostname(TLS_CONNECT *conn, const char *hostname)
conn->hostname = hostname;
return 1;
}
*/
int tls_set_socket(TLS_CONNECT *conn, tls_socket_t sock)
{
@@ -2724,8 +2806,6 @@ int tls_get_verify_result(TLS_CONNECT *conn, int *result)
return 1;
}
int tls_uint16array_from_file(uint8_t *arr, size_t *arrlen, size_t maxlen, FILE *fp)
{
uint16_t datalen;
@@ -2764,5 +2844,23 @@ int tls_uint16array_from_file(uint8_t *arr, size_t *arrlen, size_t maxlen, FILE
return 1;
}
int tls_set_server_name(TLS_CONNECT *conn, const uint8_t *host_name, size_t host_name_len)
{
if (!conn || !host_name || !host_name_len) {
error_print();
return -1;
}
if (!conn->is_client) {
error_print();
return -1;
}
if (host_name_len >= sizeof(conn->server_name)) {
error_print();
return -1;
}
memcpy(conn->server_name, host_name, host_name_len);
conn->server_name[host_name_len] = 0;
conn->server_name_len = host_name_len;
return 1;
}

View File

@@ -194,6 +194,122 @@ int tls_named_curve_from_oid(int oid)
}
/*
session_ticket_key
* server_only
* server encrypt and send NewSessionTicket
* server decrypt ClientHello.pre_shared_key
*/
int tls13_ctx_set_session_ticket_key(TLS_CTX *ctx, const uint8_t *key, size_t keylen)
{
if (!ctx || !key || !keylen) {
error_print();
return -1;
}
if (ctx->is_client) {
error_print();
return -1;
}
if (keylen != SM4_KEY_SIZE) {
error_print();
return -1;
}
sm4_set_encrypt_key(&ctx->_session_ticket_key, key);
ctx->session_ticket_key = &ctx->_session_ticket_key;
return 1;
}
#define TLS_MAX_NEW_SESSION_TICKETS 5
int tls13_ctx_set_new_session_ticket(TLS_CTX *ctx, size_t new_session_ticket_cnt)
{
if (!ctx) {
error_print();
return -1;
}
if (new_session_ticket_cnt > TLS_MAX_NEW_SESSION_TICKETS) {
error_print();
return -1;
}
ctx->new_session_ticket = (int)new_session_ticket_cnt;
return 1;
}
int tls13_set_new_session_ticket(TLS_CONNECT *conn, size_t new_session_ticket_cnt)
{
if (!conn) {
error_print();
return -1;
}
if (new_session_ticket_cnt > TLS_MAX_NEW_SESSION_TICKETS) {
error_print();
return -1;
}
conn->new_session_ticket = new_session_ticket_cnt;
return 1;
}
// 这两个函数还有用吗?
/*
int tls13_set_session_infile(TLS_CONNECT *conn, const char *file)
{
if (!conn || !file) {
error_print();
return -1;
}
if (!conn->is_client) {
error_print();
return -1;
}
conn->session_in = file;
return 1;
}
*/
int tls13_set_session_outfile(TLS_CONNECT *conn, const char *file)
{
if (!conn || !file) {
error_print();
return -1;
}
if (!conn->is_client) {
error_print();
return -1;
}
conn->session_out = file;
return 1;
}
@@ -402,7 +518,7 @@ int tls_send_client_hello(TLS_CONNECT *conn)
}
if (tls_record_set_handshake_client_hello(conn->record, &conn->recordlen,
conn->protocol, conn->client_random, NULL, 0,
conn->cipher_suites, conn->cipher_suites_cnt,
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt,
client_exts, client_exts_len) != 1) {
error_print();
return -1;
@@ -449,7 +565,7 @@ int tlcp_send_client_hello(TLS_CONNECT *conn)
if (tls_record_set_handshake_client_hello(conn->record, &conn->recordlen,
conn->protocol, conn->client_random, NULL, 0,
conn->cipher_suites, conn->cipher_suites_cnt,
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt,
NULL, 0) != 1) {
error_print();
return -1;
@@ -507,7 +623,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
// 服务器端如果设置了CA
if (conn->ca_certs_len)
if (conn->ctx->cacertslen)
client_verify = 1;
// 这个判断应该改为一个函数
@@ -550,7 +666,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
memcpy(conn->client_random, client_random, 32);
if (tls_cipher_suites_select(client_ciphers, client_ciphers_len,
conn->cipher_suites, conn->cipher_suites_cnt,
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt,
&conn->cipher_suite) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_insufficient_security);
@@ -559,7 +675,7 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
switch (conn->cipher_suite) {
case TLS_cipher_ecc_sm4_cbc_sm3:
conn->sig_alg = TLS_sig_sm2sig_sm3;
conn->signature_algorithms[0] = TLS_sig_sm2sig_sm3;
conn->ecdh_named_curve = 0;
break;
case TLS_cipher_ecdhe_sm4_cbc_sm3:
@@ -621,7 +737,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
// 服务器端如果设置了CA
if (conn->ca_certs_len)
if (conn->ctx->cacertslen)
client_verify = 1;
// 这个判断应该改为一个函数
@@ -667,7 +783,7 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
// 服务器选择的cipher_suites需要和服务器准备的证书和公钥匹配
if (tls_cipher_suites_select(client_ciphers, client_ciphers_len,
conn->cipher_suites, conn->cipher_suites_cnt,
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt,
&conn->cipher_suite) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_insufficient_security);
@@ -677,11 +793,11 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
switch (conn->cipher_suite) {
case TLS_cipher_ecdhe_sm4_cbc_sm3:
case TLS_cipher_ecdhe_sm4_gcm_sm3:
conn->sig_alg = TLS_sig_sm2sig_sm3;
conn->signature_algorithms[0] = TLS_sig_sm2sig_sm3;
conn->ecdh_named_curve = TLS_curve_sm2p256v1;
break;
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
conn->sig_alg = TLS_sig_ecdsa_secp256r1_sha256;
conn->signature_algorithms[0] = TLS_sig_ecdsa_secp256r1_sha256;
conn->ecdh_named_curve = TLS_curve_secp256r1;
break;
default:
@@ -691,8 +807,9 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
if (client_exts) {
// 这些函数需要能够访问conn的内部变量
tls_process_client_hello_exts(client_exts, client_exts_len,
conn->server_exts, &conn->server_exts_len, sizeof(conn->server_exts));
// 修改处理扩展的逻辑
//tls_process_client_hello_exts(client_exts, client_exts_len,
// conn->server_exts, &conn->server_exts_len, sizeof(conn->server_exts));
}
sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
@@ -720,10 +837,13 @@ int tls_send_server_hello(TLS_CONNECT *conn)
error_print();
return -1;
}
// 修改处理扩展的逻辑把ClientHello的每个扩展处理结果分别放在conn的各个变量中
/*
if (conn->server_exts_len) {
server_exts = conn->server_exts;
server_exts_len = conn->server_exts_len;
}
*/
if (tls_record_set_handshake_server_hello(conn->record, &conn->recordlen,
conn->protocol, conn->server_random, NULL, 0,
conn->cipher_suite,
@@ -743,7 +863,7 @@ int tls_send_server_hello(TLS_CONNECT *conn)
}
sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
if (conn->ca_certs_len) {
if (conn->ctx->cacertslen) {
tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5);
}
@@ -933,7 +1053,7 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
error_print();
return -1;
}
conn->server_sig_alg = TLS_sig_sm2sig_sm3;
conn->signature_algorithms[0] = TLS_sig_sm2sig_sm3;
break;
case TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256:
@@ -941,7 +1061,7 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
error_print();
return -1;
}
conn->server_sig_alg = TLS_sig_ecdsa_secp256r1_sha256;
conn->signature_algorithms[0] = TLS_sig_ecdsa_secp256r1_sha256;
break;
default:
error_print();
@@ -953,26 +1073,26 @@ int tls_recv_server_certificate(TLS_CONNECT *conn)
sm2_sign_update(&conn->sign_ctx, conn->record + 5, conn->recordlen - 5);
}
assert(conn->verify_depth > 0 && conn->verify_depth < 10);
assert(conn->ctx->verify_depth > 0 && conn->ctx->verify_depth < 10);
// verify ServerCertificate
switch (conn->protocol) {
case TLS_protocol_tls12:
if (x509_certs_verify(conn->server_certs, conn->server_certs_len, X509_cert_chain_server,
conn->ca_certs, conn->ca_certs_len, conn->verify_depth, &verify_result) != 1) {
conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
break;
case TLS_protocol_tlcp:
if (!conn->ca_certs_len) {
if (!conn->ctx->cacertslen) {
error_print();
return -1;
}
if (x509_certs_verify_tlcp(conn->server_certs, conn->server_certs_len, X509_cert_chain_server,
conn->ca_certs, conn->ca_certs_len, conn->verify_depth, &verify_result) != 1) {
conn->ctx->cacerts, conn->ctx->cacertslen, conn->ctx->verify_depth, &verify_result) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
@@ -1100,7 +1220,7 @@ int tls_send_server_key_exchange(TLS_CONNECT *conn)
if (tls_record_set_handshake_server_key_exchange(conn->record, &conn->recordlen,
server_ecdh_params, sizeof(server_ecdh_params),
conn->sig_alg, sig, siglen) != 1) {
conn->signature_algorithms[0], sig, siglen) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_internal_error);
return -1;
@@ -1424,7 +1544,7 @@ int tls_send_certificate_request(TLS_CONNECT *conn)
if (conn->recordlen == 0) {
tls_trace("send CertificateRequest\n");
if (tls_authorities_from_certs(ca_names, &ca_names_len, sizeof(ca_names),
conn->ca_certs, conn->ca_certs_len) != 1) {
conn->ctx->cacerts, conn->ctx->cacertslen) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_internal_error);
return -1;
@@ -1624,7 +1744,7 @@ int tls_recv_client_certificate(TLS_CONNECT *conn)
tls_trace("recv ClientCertificate\n");
if (conn->ca_certs_len == 0) {
if (conn->ctx->cacertslen == 0) {
error_print();
return -1;
}
@@ -1647,7 +1767,7 @@ int tls_recv_client_certificate(TLS_CONNECT *conn)
return -1;
}
if (x509_certs_verify(conn->client_certs, conn->client_certs_len, X509_cert_chain_client,
conn->ca_certs, conn->ca_certs_len, verify_depth, &verify_result) != 1) {
conn->ctx->cacerts, conn->ctx->cacertslen, verify_depth, &verify_result) != 1) {
error_print();
tls_send_alert(conn, TLS_alert_bad_certificate);
return -1;
@@ -1867,7 +1987,7 @@ int tls_recv_client_key_exchange(TLS_CONNECT *conn)
conn->peer_ecdh_point_len = point_octets_len;
sm3_update(&conn->sm3_ctx, conn->record + 5, conn->recordlen - 5);
if (conn->ca_certs_len)
if (conn->ctx->cacertslen)
tls_client_verify_update(&conn->client_verify_ctx, conn->record + 5, conn->recordlen - 5);
return 1;
@@ -2756,3 +2876,420 @@ int tls12_do_accept(TLS_CONNECT *conn)
return 1;
}
/*
status_request(5)
这个扩展在客户端和服务器端中是不同的
ClientHello.status_request
struct {
CertificateStatusType status_type = ocsp(1);
opaque request<0..2^16-1>;
} CertificateStatusRequest;
其中request中是
struct {
ResponderID responder_id_list<0..2^16-1>;
Extensions request_extensions;
} OCSPStatusRequest;
------------------------------------------------------
server Certificate
struct {
CertificateStatusType status_type;
opaque response<1..2^24-1>;
} CertificateStatus;
response中的数据是就是一个原始的OCSP的response我们将其视为二进制数据
在TLS 1.2中如果服务器同意status_request会在ServerHello中返回一个空的status_request
并且会返回一个独立的CertificateStatus握手消息
*/
int tls_ocsp_status_request_to_bytes(
const uint8_t *responder_id_list, size_t responder_id_list_len,
const uint8_t *request_exts, size_t request_exts_len,
uint8_t **out, size_t *outlen)
{
uint8_t **pp = out;
size_t request_len = 0;
size_t len;
if (!outlen) {
error_print();
return -1;
}
tls_uint16_to_bytes(0, out, &len);
tls_uint16array_to_bytes(responder_id_list, responder_id_list_len, out, &request_len);
tls_uint16array_to_bytes(request_exts, request_exts_len, out, &request_len);
tls_uint16array_to_bytes(NULL, request_len, pp, outlen);
return 1;
}
int tls_ocsp_status_request_from_bytes(
const uint8_t **responder_id_list, size_t *responder_id_list_len,
const uint8_t **request_exts, size_t *request_exts_len,
const uint8_t **in, size_t *inlen)
{
const uint8_t *request;
size_t request_len;
if (!responder_id_list || !responder_id_list_len || !request_exts || !request_exts_len
|| !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_uint16array_from_bytes(&request, &request_len, in, inlen) != 1) {
error_print();
return -1;
}
if (!request) {
*responder_id_list = NULL;
*responder_id_list_len = 0;
*request_exts = NULL;
*request_exts_len = 0;
return 1;
}
if (tls_uint16array_from_bytes(responder_id_list, responder_id_list_len, &request, &request_len) != 1
|| tls_uint16array_from_bytes(request_exts, request_exts_len, &request, &request_len) != 1
|| tls_length_is_zero(request_len) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_ocsp_status_request_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *ext_data, size_t ext_datalen)
{
const uint8_t *request;
size_t request_len;
const uint8_t *responder_id_list;
size_t responder_id_list_len;
const uint8_t *request_exts;
size_t request_exts_len;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if (tls_uint16array_from_bytes(&request, &request_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
if (!request) {
format_print(fp, fmt, ind, "(null)\n");
if (ext_datalen) {
format_print(fp, fmt, ind, "error: left %zu bytes\n", ext_datalen);
return -1;
}
return 1;
}
if (tls_uint16array_from_bytes(&responder_id_list, &responder_id_list_len, &request, &request_len) != 1
|| tls_uint16array_from_bytes(&request_exts, &request_exts_len, &request, &request_len) != 1) {
error_print();
return -1;
}
while (responder_id_list_len) {
const uint8_t *responder_id;
size_t responder_id_len;
if (tls_uint16array_from_bytes(&responder_id, &responder_id_len,
&responder_id_list, &responder_id_list_len) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, ind + 4, "ResponderID", responder_id, responder_id_len);
}
while (request_exts_len) {
int ext_type;
const uint8_t *ext_data;
size_t ext_datalen;
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &request_exts, &request_exts_len) != 1) {
error_print();
return -1;
}
// print
}
return 1;
}
/*
struct {
CertificateStatusType status_type = ocsp(1);
opaque request<0..2^16-1>;
} CertificateStatusRequest;
*/
int tls_client_status_request_ext_to_bytes(int status_type,
const uint8_t *responder_id_list, size_t responder_id_list_len,
const uint8_t *request_exts, size_t request_exts_len,
uint8_t **out, size_t *outlen)
{
int ext_type = TLS_extension_status_request;
size_t ext_datalen = 0;
uint8_t **pp = out;
size_t len;
if (!outlen) {
error_print();
return -1;
}
tls_ext_to_bytes(ext_type, NULL, 0, out, &len);
tls_uint8_to_bytes(status_type, out, &ext_datalen);
tls_ocsp_status_request_to_bytes(responder_id_list, responder_id_list_len,
request_exts, request_exts_len, out, &ext_datalen);
tls_ext_to_bytes(ext_type, NULL, ext_datalen, pp, outlen);
return 1;
}
int tls_client_status_request_from_bytes(int *status_type,
const uint8_t **responder_id_list, size_t *responder_id_list_len,
const uint8_t **request_exts, size_t *request_exts_len,
const uint8_t *ext_data, size_t ext_datalen)
{
uint8_t status;
if (!status_type || !responder_id_list || !responder_id_list_len
|| !request_exts || !request_exts_len || !ext_data || !ext_datalen) {
error_print();
return -1;
}
if (tls_uint8_from_bytes(&status, &ext_data, &ext_datalen) != 1
|| tls_ocsp_status_request_from_bytes(responder_id_list, responder_id_list_len,
request_exts, request_exts_len, &ext_data, &ext_datalen) != 1
|| tls_length_is_zero(ext_datalen) != 1) {
error_print();
return -1;
}
*status_type = status;
return 1;
}
int tls_client_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
{
uint8_t status_type;
const uint8_t *request;
size_t request_len;
if (tls_uint8_from_bytes(&status_type, &ext_data, &ext_datalen) != 1
|| tls_uint16array_from_bytes(&request, &request_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "status_type: %s (%d)\n", status_type == TLS_certificate_status_type_ocsp ? "ocsp" : NULL, status_type);
request -= tls_uint16_size();
request_len += tls_uint16_size();
tls_ocsp_status_request_print(fp, fmt, ind, "request", request, request_len);
return 1;
}
//----------------------------------------------------------------------------
int ocsp_response_verify(const uint8_t *ocsp_response, size_t ocsp_response_len,
const uint8_t *ca_certs, size_t ca_certs_len)
{
return 1;
}
int tls_server_status_request_ext_to_bytes(const uint8_t *ocsp_response, size_t ocsp_response_len,
uint8_t **out, size_t *outlen)
{
int ext_type = TLS_extension_status_request;
size_t ext_datalen = 0;
uint8_t **pp = out;
size_t len;
if (!ocsp_response || !ocsp_response_len || !outlen) {
error_print();
return -1;
}
tls_ext_to_bytes(ext_type, NULL, 0, out, &len);
tls_uint24array_to_bytes(ocsp_response, ocsp_response_len, out, &ext_datalen);
tls_ext_to_bytes(ext_type, NULL, ext_datalen, pp, outlen);
return 1;
}
int tls_server_status_request_from_bytes(const uint8_t **ocsp_response, size_t *ocsp_response_len,
const uint8_t *ext_data, size_t ext_datalen)
{
if (!ocsp_response || !ocsp_response_len || !ext_data || !ext_datalen) {
error_print();
return -1;
}
if (tls_uint24array_from_bytes(ocsp_response, ocsp_response_len, &ext_data, &ext_datalen) != 1
|| tls_length_is_zero(ext_datalen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_server_status_request_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
{
const uint8_t *ocsp_response;
size_t ocsp_response_len;
if (tls_uint24array_from_bytes(&ocsp_response, &ocsp_response_len, &ext_data, &ext_datalen) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, ind, "ocsp_response", ocsp_response, ocsp_response_len);
if (ext_datalen) {
error_print();
return -1;
}
return 1;
}
/*
signed_certificate_timestamp
struct {
opaque sct_list<1..2^16-1>;
} SignedCertificateTimestampList;
*/
/*
signed_certificate_timestamp (CT)
这是一个tls13的扩展
这个扩展只在ServerCertificate, ClientCertificate握手消息的扩展中
这个扩展主要是提供一个格外的信息:
证书透明度CT日志服务器签发的“证书存在证明”的扩展。
struct {
opaque key_id[32]; // 日志服务器ID
uint64 timestamp; // 证书提交时间戳
opaque signature<0..2^16-1>; // 日志服务器签名
} SignedCertificateTimestamp;
struct {
SignedCertificateTimestamp sct_list<0..2^16-1>;
} SignedCertificateTimestampList;
*/
int tls_signed_certificate_timestamp_entry_to_bytes(const uint8_t key_id[32],
uint64_t timestamp, const uint8_t *signature, size_t signature_len,
uint8_t **out, size_t *outlen)
{
if (!key_id || !signature || !signature_len || !outlen) {
error_print();
return -1;
}
tls_array_to_bytes(key_id, 32, out, outlen);
tls_uint64_to_bytes(timestamp, out, outlen);
tls_uint16array_to_bytes(signature, signature_len, out, outlen);
return 1;
}
int tls_signed_certificate_timestamp_entry_from_bytes(const uint8_t **key_id,
uint64_t *timestamp, const uint8_t **signature, size_t *signature_len,
const uint8_t **in, size_t *inlen)
{
if (!key_id || !timestamp || !signature || !signature_len || !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_array_from_bytes(key_id, 32, in, inlen) != 1
|| tls_uint64_from_bytes(timestamp, in, inlen) != 1
|| tls_uint16array_from_bytes(signature, signature_len, in, inlen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_signed_certificate_timestamp_ext_to_bytes(const uint8_t *sct_list, size_t sct_list_len,
uint8_t **out, size_t *outlen)
{
if (!sct_list || !sct_list_len || !outlen) {
error_print();
return -1;
}
tls_uint16array_to_bytes(sct_list, sct_list_len, out, outlen);
return 1;
}
int tls_signed_certificate_timestamp_from_bytes(const uint8_t **sct_list, size_t *sct_list_len,
const uint8_t **in, size_t *inlen)
{
if (!sct_list || !sct_list_len || !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (tls_uint16array_from_bytes(sct_list, sct_list_len, in, inlen) != 1) {
error_print();
return -1;
}
return 1;
}
int tls_signed_certificate_timestamp_print(FILE *fp, int fmt, int ind,
const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *sct_list;
size_t sct_list_len;
if (tls_uint16array_from_bytes(&sct_list, &sct_list_len, &d, &dlen) != 1) {
error_print();
return -1;
}
format_print(fp, fmt, ind, "sct_list\n");
ind += 4;
if (!sct_list_len) {
format_print(fp, fmt, ind, "(null)\n");
}
while (sct_list_len) {
const uint8_t *key_id;
uint64_t timestamp;
const uint8_t *signature;
size_t signature_len;
int entry_ind = ind + 4;
format_print(fp, fmt, ind, "SignedCertificateTimestamp\n");
if (tls_array_from_bytes(&key_id, 32, &sct_list, &sct_list_len) != 1
|| tls_uint64_from_bytes(&timestamp, &sct_list, &sct_list_len) != 1
|| tls_uint16array_from_bytes(&signature, &signature_len, &sct_list, &sct_list_len) != 1) {
error_print();
return -1;
}
format_bytes(fp, fmt, entry_ind, "key_id", key_id, 32);
format_print(fp, fmt, entry_ind, "timestamp: %"PRIu64"\n", timestamp);
format_bytes(fp, fmt, entry_ind, "signature", signature, signature_len);
if (dlen) {
error_print();
return -1;
}
}
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <gmssl/ec.h>
#include <gmssl/tls.h>
#include <gmssl/x509.h>
#include <gmssl/error.h>
@@ -44,6 +45,18 @@ const char *tls_protocol_name(int protocol)
return NULL;
}
int tls_protocol_from_name(const char *name)
{
if (!strcmp(name, "TLS1.3")) {
return TLS_protocol_tls13;
} else if (!strcmp(name, "TLS1.2")) {
return TLS_protocol_tls12;
} else if (!strcmp(name, "TLCP")) {
return TLS_protocol_tlcp;
}
return 0;
}
const char *tls_cipher_suite_name(int cipher)
{
switch (cipher) {
@@ -73,6 +86,23 @@ const char *tls_cipher_suite_name(int cipher)
return NULL;
}
int tls_cipher_suite_from_name(const char *name)
{
if (!strcmp(name, "TLS_SM4_GCM_SM3")) {
return TLS_cipher_sm4_gcm_sm3;
} else if (!strcmp(name, "TLS_AES_128_GCM_SHA256")) {
return TLS_cipher_aes_128_gcm_sha256;
} else if (!strcmp(name, "TLS_ECDHE_SM4_CBC_SM3")) {
return TLS_cipher_ecdhe_sm4_cbc_sm3;
} else if (!strcmp(name, "TLS_ECC_SM4_CBC_SM3")) {
return TLS_cipher_ecc_sm4_cbc_sm3;
} else if (!strcmp(name, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256")) {
return TLS_cipher_ecdhe_ecdsa_with_aes_128_cbc_sha256;
}
error_print();
return 0;
}
const char *tls_compression_method_name(int meth)
{
switch (meth) {
@@ -238,6 +268,7 @@ const char *tls_alert_description_text(int description)
case TLS_alert_bad_ibcparam: return "bad_ibcparam";
case TLS_alert_unsupported_ibcparam: return "unsupported_ibcparam";
case TLS_alert_identity_need: return "identity_need";
case TLS_alert_missing_extension: return "missing_extension";
}
error_print_msg("unknown alert description %d", description);
return NULL;
@@ -291,6 +322,20 @@ const char *tls_named_curve_name(int curve)
return NULL;
}
int tls_named_curve_from_name(const char *name)
{
int oid;
if ((oid = ec_named_curve_from_name(name)) == OID_undef) {
return 0;
}
switch (oid) {
case OID_sm2:
case OID_secp256r1:
return tls_named_curve_from_oid(oid);
}
return 0;
}
const char *tls_signature_scheme_name(int scheme)
{
switch (scheme) {
@@ -321,6 +366,35 @@ const char *tls_signature_scheme_name(int scheme)
return NULL;
}
int tls_signature_scheme_from_name(const char *name)
{
if (!strcmp(name, "ecdsa_secp256r1_sha256")) {
return TLS_sig_ecdsa_secp256r1_sha256;
} else if (!strcmp(name, "sm2sig_sm3")) {
return TLS_sig_sm2sig_sm3;
}
return 0;
}
int tls_signature_scheme_algorithm_oid(int sig_alg)
{
switch (sig_alg) {
case TLS_sig_sm2sig_sm3: return OID_sm2sign_with_sm3;
case TLS_sig_ecdsa_secp256r1_sha256: return OID_ecdsa_with_sha256;
}
return 0;
}
int tls_signature_scheme_group_oid(int sig_alg)
{
switch (sig_alg) {
case TLS_sig_sm2sig_sm3: return OID_sm2;
case TLS_sig_ecdsa_secp256r1_sha256: return OID_secp256r1;
}
return 0;
}
// 这个函数去掉
int tls_signature_scheme_oid(int sig_alg)
{
switch (sig_alg) {
@@ -330,6 +404,7 @@ int tls_signature_scheme_oid(int sig_alg)
return 0;
}
// 这个函数也应该修改,必须同时提供算法/group
int tls_signature_scheme_from_oid(int sig_alg_oid)
{
switch (sig_alg_oid) {

View File

@@ -1594,6 +1594,47 @@ int x509_cert_get_exts(const uint8_t *a, size_t alen, const uint8_t **d, size_t
return 1;
}
// compre host_name of server_name (SNI) extension with SubjectAltName.dnsName
int x509_cert_get_subject_alt_name_dns_name(const uint8_t *a, size_t alen, const uint8_t **dns_name, size_t *dns_name_len)
{
const uint8_t *exts;
size_t extslen;
const uint8_t *general_names;
size_t general_names_len;
int choice = X509_gn_dns_name;
int critical;
int ret;
if (!a || !alen || !dns_name || !dns_name_len) {
error_print();
return -1;
}
*dns_name = NULL;
*dns_name_len = 0;
if ((ret = x509_cert_get_exts(a, alen, &exts, &extslen)) < 0) {
error_print();
return -1;
} else if (ret == 0) {
return 0;
}
if ((ret = x509_exts_get_ext_by_oid(exts, extslen, OID_ce_subject_alt_name,
&critical, &general_names, &general_names_len)) < 0) {
error_print();
return -1;
} else if (ret == 0) {
return 0;
}
if ((ret = x509_general_names_get_first(general_names, general_names_len,
NULL, choice, dns_name, dns_name_len)) < 0) {
error_print();
return -1;
} else if (ret == 0) {
return 0;
}
return 1;
}
int x509_cert_get_signature_algor(const uint8_t *a, size_t alen, int *oid)
{
int inner_alg;

View File

@@ -1297,6 +1297,7 @@ int x509_private_key_info_encrypt_to_pem(const X509_KEY *key, const char *pass,
int x509_private_key_info_decrypt_from_pem(X509_KEY *key, const uint8_t **attrs, size_t *attrslen, const char *pass, FILE *fp)
{
int ret;
uint8_t buf[512];
const uint8_t *cp = buf;
size_t len;
@@ -1305,9 +1306,11 @@ int x509_private_key_info_decrypt_from_pem(X509_KEY *key, const uint8_t **attrs,
error_print();
return -1;
}
if (pem_read(fp, "ENCRYPTED PRIVATE KEY", buf, &len, sizeof(buf)) != 1) {
if ((ret = pem_read(fp, "ENCRYPTED PRIVATE KEY", buf, &len, sizeof(buf))) < 0) {
error_print();
return -1;
} else if (ret == 0) {
return 0;
}
if (x509_private_key_info_decrypt_from_der(key, attrs, attrslen, pass, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
@@ -1325,15 +1328,18 @@ int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE
}
if (algor == OID_ec_public_key) {
int ret;
const uint8_t *attrs;
size_t attrslen;
if (!pass) {
error_print();
return -1;
}
if (x509_private_key_info_decrypt_from_pem(key, &attrs, &attrslen, pass, fp) != 1) {
if ((ret = x509_private_key_info_decrypt_from_pem(key, &attrs, &attrslen, pass, fp)) < 0) {
error_print();
return -1;
} else if (ret == 0) {
return 0; // TODO: support return 0 for other algors
}
} else if (algor == OID_lms_hashsig) {
uint8_t buf[LMS_PRIVATE_KEY_SIZE];
@@ -1420,6 +1426,32 @@ int x509_private_key_from_file(X509_KEY *key, int algor, const char *pass, FILE
return 1;
}
int x509_private_keys_from_file(X509_KEY *keys, size_t *keys_cnt, size_t max_cnt,
int algor, const char *pass, FILE *fp)
{
size_t i;
if (!keys || !keys_cnt || !pass || !fp) {
error_print();
return -1;
}
for (i = 0; i < max_cnt; i++) {
int ret;
if ((ret = x509_private_key_from_file(&keys[i], algor, pass, fp)) < 0) {
error_print();
return -1;
} else if (ret == 0) {
break;
}
}
*keys_cnt = i;
if (i == 0) {
return 0;
}
return 1;
}
int x509_key_get_sign_algor(const X509_KEY *key, int *algor)
{
if (!key || !algor) {