Update TLS 1.3

This commit is contained in:
Zhi Guan
2026-05-07 20:57:46 +08:00
parent c23e117537
commit 4c54385534
12 changed files with 480 additions and 82 deletions

View File

@@ -433,6 +433,7 @@ if (ENABLE_SECP256R1)
message(STATUS "ENABLE_SECP256R1 is ON")
add_definitions(-DENABLE_SECP256R1)
list(APPEND src src/secp256r1.c src/secp256r1_key.c src/ecdsa.c src/ecdh.c)
list(APPEND tools tools/p256keygen.c)
list(APPEND tests secp256r1 secp256r1_key ecdsa)
endif()

View File

@@ -107,6 +107,8 @@ int x509_private_key_print_ex(FILE *fp, int fmt, int ind, const char *label, con
#define X509_PUBLIC_KEY_INFO_MAX_SIZE 1280 // for kyber and 91 for others
int x509_public_key_info_to_der(const X509_KEY *key, uint8_t **out, size_t *outlen);
int x509_public_key_info_from_der(X509_KEY *key, const uint8_t **in, size_t *inlen);
int x509_public_key_info_to_pem(const X509_KEY *a, FILE *fp);
int x509_public_key_info_from_pem(X509_KEY *a, FILE *fp);
int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);

View File

@@ -199,8 +199,8 @@ int secp256r1_public_key_from_der(SECP256R1_KEY *key, const uint8_t **in, size_t
}
// 这里应该提供public_key_info_to_pem 和SM2完全一样的功能
// 这样才可以生成证书

View File

@@ -2780,6 +2780,8 @@ int tls_init(TLS_CONNECT *conn, TLS_CTX *ctx)
return -1;
}
fprintf(stderr, "%s %d: conn->key_exchange_modes = %d\n", __FILE__, __LINE__, conn->key_exchange_modes);
if (conn->key_exchange_modes & (TLS_KE_CERT_DHE|TLS_KE_PSK_DHE)) {
conn->key_share = 1;

View File

@@ -316,7 +316,7 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
*sentlen = 0;
// 这个可能是有问题的
if (!conn->recordlen) {
const BLOCK_CIPHER_KEY *key;
const uint8_t *iv;
@@ -336,13 +336,23 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
format_bytes(stderr, 0, 4, "client_write_iv", iv, 12);
format_bytes(stderr, 0, 4, "client_seq_num", seq_num, 8);
format_print(stderr, 0, 0, "\n");
} else {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
format_bytes(stderr, 0, 4, "server_write_iv", iv, 12);
format_bytes(stderr, 0, 4, "server_seq_num", seq_num, 8);
format_print(stderr, 0, 0, "\n");
}
tls13_padding_len_rand(&padding_len);
// 这个其实不太好最好是直接加密一个record这样我们可以打印出record
if (tls13_gcm_encrypt(key, iv,
seq_num, TLS_record_application_data, data, datalen, padding_len,
conn->record + 5, &record_datalen) != 1) {
@@ -350,7 +360,6 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
return -1;
}
tls_seq_num_incr(seq_num);
tls_record_set_type(conn->record, TLS_record_application_data);
tls_record_set_protocol(conn->record, TLS_protocol_tls12);
tls_record_set_data_length(conn->record, record_datalen);
@@ -359,6 +368,11 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
conn->record_offset = 0;
conn->plain_recordlen = datalen + 5;
tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen);
/*
KeyUpdate有两个原因
* 我们自己检查应该KeyUpdate了那么发送KeyUpdate并且要求对方也Update
@@ -367,9 +381,12 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
*/
// check if KeyUpdate
/*
// key_update_seq_num_limit 似乎还没有设置
if (GETU64(seq_num) >= conn->ctx->key_update_seq_num_limit) {
key_update = 1;
}
*/
}
while (conn->recordlen) {
@@ -390,7 +407,7 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
conn->record_offset += n;
}
/*
if (key_update) {
int ret;
@@ -416,10 +433,11 @@ int tls13_send(TLS_CONNECT *conn, const uint8_t *data, size_t datalen, size_t *s
}
}
*/
*sentlen = conn->plain_recordlen - 5;
return 1;
}
@@ -434,11 +452,15 @@ int tls13_do_recv(TLS_CONNECT *conn)
switch (conn->state) {
case 0:
error_print();
fprintf(stderr, "----------------------------------------------------------------\n");
conn->record_offset = 0;
conn->recordlen = TLS_RECORD_HEADER_SIZE;
conn->state = TLS_state_recv_record_header;
error_print();
case TLS_state_recv_record_header:
error_print();
while (conn->recordlen) {
if ((n = tls_socket_recv(conn->sock, conn->record + conn->record_offset, conn->recordlen, 0)) <= 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
@@ -449,6 +471,7 @@ int tls13_do_recv(TLS_CONNECT *conn)
}
}
conn->recordlen -= n;
conn->record_offset += n;
}
if (tls_record_type(conn->record) != TLS_record_application_data) {
error_print();
@@ -458,10 +481,17 @@ int tls13_do_recv(TLS_CONNECT *conn)
error_print();
return -1;
}
conn->recordlen = tls_record_length(conn->record);
conn->recordlen = tls_record_data_length(conn->record);
fprintf(stderr, "%d: recordlen = %zu\n", __LINE__, conn->recordlen);
fprintf(stderr, "record_offset = %zu\n", conn->record_offset);
conn->state = TLS_state_recv_record_data;
case TLS_state_recv_record_data:
error_print();
while (conn->recordlen) {
if ((n = tls_socket_recv(conn->sock, conn->record + conn->record_offset, conn->recordlen, 0)) <= 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
@@ -472,6 +502,7 @@ int tls13_do_recv(TLS_CONNECT *conn)
}
}
conn->recordlen -= n;
conn->record_offset += n;
}
conn->state = 0;
break;
@@ -480,18 +511,35 @@ int tls13_do_recv(TLS_CONNECT *conn)
error_print();
return -1;
}
conn->recordlen = tls_record_length(conn->record) + TLS_RECORD_HEADER_SIZE;
// tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen);
conn->recordlen = tls_record_length(conn->record);
fprintf(stderr, "%d: recordlen = %zu\n", __LINE__, conn->recordlen);
tls13_record_print(stderr, 0, 0, conn->record, conn->recordlen);
if (conn->is_client) {
key = &conn->server_write_key;
iv = conn->server_write_iv;
seq_num = conn->server_seq_num;
format_bytes(stderr, 0, 4, "server_write_iv", iv, 12);
format_bytes(stderr, 0, 4, "server_seq_num", seq_num, 8);
format_print(stderr, 0, 0, "\n");
} else {
key = &conn->client_write_key;
iv = conn->client_write_iv;
seq_num = conn->client_seq_num;
format_bytes(stderr, 0, 4, "client_write_iv", iv, 12);
format_bytes(stderr, 0, 4, "client_seq_num", seq_num, 8);
format_print(stderr, 0, 0, "\n");
}
if (tls13_record_decrypt(key, iv, seq_num, conn->record, conn->recordlen,
conn->plain_record, &conn->plain_recordlen) != 1) {
error_print();
@@ -499,6 +547,8 @@ int tls13_do_recv(TLS_CONNECT *conn)
}
tls_seq_num_incr(seq_num);
tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
switch (tls_record_type(conn->plain_record)) {
case TLS_record_application_data:
conn->data = conn->plain_record + 5;
@@ -520,6 +570,10 @@ int tls13_do_recv(TLS_CONNECT *conn)
// NewSessionTicket 也不应该是被单独接收的只能在解密并解析了handshake之后才可以
case TLS_handshake_new_session_ticket:
error_print();
fprintf(stderr, "tls13_process_new_session_ticket\n");
if (tls13_process_new_session_ticket(conn) != 1) {
error_print();
return -1;
@@ -609,6 +663,9 @@ int tls13_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen)
error_print();
return -1;
}
fprintf(stderr, "%d: conn->state %d\n", __LINE__, conn->state);
if (conn->datalen == 0) {
int ret;
if ((ret = tls13_do_recv(conn)) != 1) {
@@ -620,6 +677,12 @@ int tls13_recv(TLS_CONNECT *conn, uint8_t *out, size_t outlen, size_t *recvlen)
memcpy(out, conn->data, *recvlen);
conn->data += *recvlen;
conn->datalen -= *recvlen;
// 这里接受完成之后应该recordlen = 0
conn->recordlen = 0;
return 1;
}
@@ -695,8 +758,12 @@ int tls13_derive_secret(const uint8_t secret[32], const char *label, const DIGES
uint8_t dgst[64];
size_t dgstlen;
if (digest_finish(&ctx, dgst, &dgstlen) != 1
|| tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) {
if (digest_finish(&ctx, dgst, &dgstlen) != 1) {
error_print();
return -1;
}
if (tls13_hkdf_expand_label(dgst_ctx->digest, secret, label, dgst, 32, dgstlen, out) != 1) {
error_print();
return -1;
}
@@ -3286,16 +3353,24 @@ Auth | {CertificateVerify*}
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;
@@ -3500,11 +3575,16 @@ int tls13_init(TLS_CONNECT *conn, TLS_CTX *ctx)
// key_exchange_modes
conn->key_exchange_modes = ctx->psk_key_exchange_modes;
if (ctx->supported_groups_cnt && ctx->signature_algorithms_cnt) {
conn->key_exchange_modes = TLS_KE_CERT_DHE;
conn->key_exchange_modes |= TLS_KE_CERT_DHE;
}
if (!ctx->supported_groups_cnt) {
conn->key_exchange_modes &= ~(TLS_KE_CERT_DHE|TLS_KE_PSK_DHE);
}
tls_key_exchange_modes_print(stderr, 0, 0, "server key_exchange_modes", conn->key_exchange_modes);
if (!conn->key_exchange_modes) {
error_print();
return -1;
@@ -3529,6 +3609,11 @@ int tls13_init(TLS_CONNECT *conn, TLS_CTX *ctx)
}
/*
ClientHello中的很多扩展是和证书有关的
如果客户端在ClientHello中已经明确不支持证书认证没有提供group + sig_alg的组合
那么就不应该在ClientHello中包含这些扩展
*/
int tls13_send_client_hello(TLS_CONNECT *conn)
{
@@ -3703,6 +3788,9 @@ int tls13_send_client_hello(TLS_CONNECT *conn)
}
}
fprintf(stderr, ">>>>> conn->pre_shared_key = %d\n", conn->pre_shared_key);
// pre_shared_key (must be the last extension)
if (conn->pre_shared_key) {
uint8_t *ptruncated_exts = pexts;
@@ -3711,6 +3799,9 @@ int tls13_send_client_hello(TLS_CONNECT *conn)
uint8_t *pbinders = binders;
size_t binderslen = 0;
fprintf(stderr, "add pre_shared_key\n");
if (!conn->psk_identities_len
|| !conn->psk_keys_len
|| !conn->psk_cipher_suites_cnt ) {
@@ -5682,6 +5773,9 @@ int tls13_recv_server_certificate_verify(TLS_CONNECT *conn)
return -1;
}
conn->recordlen = 0;
conn->plain_recordlen = 0;
return 1;
}
@@ -5759,18 +5853,7 @@ int tls13_recv_client_certificate_verify(TLS_CONNECT *conn)
}
// ServerFinished消息之前有可能是什么消息
int tls13_recv_server_finished(TLS_CONNECT *conn)
{
@@ -5790,6 +5873,9 @@ int tls13_recv_server_finished(TLS_CONNECT *conn)
}
tls_trace("recv server {Finished}\n");
if (!conn->plain_recordlen) {
if ((ret = tls_recv_record(conn)) != 1) {
if (ret != TLS_ERROR_RECV_AGAIN) {
error_print();
@@ -5805,7 +5891,9 @@ int tls13_recv_server_finished(TLS_CONNECT *conn)
return -1;
}
tls_seq_num_incr(conn->server_seq_num);
}
tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
if (digest_update(&conn->dgst_ctx, conn->plain_record + 5, conn->plain_recordlen - 5) != 1) {
error_print();
return -1;
@@ -5846,9 +5934,10 @@ int tls13_recv_server_finished(TLS_CONNECT *conn)
format_bytes(stderr, 0, 4, "server_application_traffic_secret", conn->server_application_traffic_secret, 48);
format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16);
format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12);
format_bytes(stderr, 0, 4, "server_seq_num", conn->server_seq_num, 8);
format_print(stderr, 0, 0, "\n");
tls_seq_num_reset(conn->server_seq_num);
return 1;
}
@@ -6699,7 +6788,7 @@ int tls13_recv_client_hello(TLS_CONNECT *conn)
return -1;
}
//tls_key_exchange_modes_print(stderr, 0, 0, ">>>> key_exchange_modes", conn->key_exchange_modes);
tls_key_exchange_modes_print(stderr, 0, 0, "server key_exchange_mode", conn->key_exchange_modes);
// hello_retry_request
if (conn->hello_retry_request) {
@@ -7709,6 +7798,7 @@ int tls13_send_server_finished(TLS_CONNECT *conn)
format_bytes(stderr, 0, 4, "server_application_traffic_secret", conn->server_application_traffic_secret, 48);
format_bytes(stderr, 0, 4, "server_write_key", server_write_key, 16);
format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12);
format_bytes(stderr, 0, 4, "server_seq_num", conn->server_seq_num, 8);
format_print(stderr, 0, 0, "\n");
}
@@ -8384,8 +8474,13 @@ int tls13_client_handshake(TLS_CONNECT *conn)
}
return ret;
}
}
conn->state = 0;
// TODO: cleanup conn?
return 1;
@@ -8407,6 +8502,8 @@ int tls13_server_handshake(TLS_CONNECT *conn)
}
}
conn->state = 0;
// TODO: cleanup conn?
return 1;

View File

@@ -581,6 +581,8 @@ int tls13_session_print(FILE *fp, int fmt, int ind, const char *label, const uin
return 1;
}
// 需要检查一下加入的SESSION的cipher_suite是否和conn的匹配
// client only
int tls13_add_pre_shared_key_from_session_file(TLS_CONNECT *conn, FILE *fp)
{
@@ -664,20 +666,24 @@ int tls13_send_new_session_ticket(TLS_CONNECT *conn)
uint32_t max_early_data_size = 256 * 1024; // 256 KB
uint32_t ticket_issue_time = time(NULL);
uint8_t resumption_master_secret[48];
size_t dgstlen = 32;
uint8_t pre_shared_key[32];
if (rand_bytes((uint8_t *)&ticket_age_add, sizeof(ticket_age_add)) != 1) {
error_print();
return -1;
}
if (rand_bytes(ticket_nonce, sizeof(ticket_nonce)) != 1) {
error_print();
return -1;
}
uint8_t resumption_master_secret[48];
size_t dgstlen = 32;
uint8_t pre_shared_key[32];
// generate resumption_master_secret
digest_init(&conn->dgst_ctx, conn->digest);
/* [14] */ tls13_derive_secret(conn->master_secret, "res master", &conn->dgst_ctx, resumption_master_secret);
// pre_shared_key = HKDF-Expand-Label(resumption_master_secret, "resumption", ticket_nonce, Hash.length)
@@ -713,6 +719,12 @@ int tls13_send_new_session_ticket(TLS_CONNECT *conn)
}
tls13_record_print(stderr, 0, 0, conn->plain_record, conn->plain_recordlen);
format_print(stderr, 0, 0, "update server secrets\n");
format_bytes(stderr, 0, 4, "server_application_traffic_secret", conn->server_application_traffic_secret, 48);
format_bytes(stderr, 0, 4, "server_write_iv", conn->server_write_iv, 12);
format_bytes(stderr, 0, 4, "server_seq_num", conn->server_seq_num, 8);
format_print(stderr, 0, 0, "\n");
tls13_padding_len_rand(&padding_len);
if (tls13_record_encrypt(&conn->server_write_key, conn->server_write_iv,
conn->server_seq_num, conn->plain_record, conn->plain_recordlen, padding_len,
@@ -799,6 +811,8 @@ int tls13_process_new_session_ticket(TLS_CONNECT *conn)
size_t dgstlen = 32;
uint8_t pre_shared_key[32];
digest_init(&conn->dgst_ctx, conn->digest);
// generate resumption_master_secret
/* [14] */ tls13_derive_secret(conn->master_secret, "res master", &conn->dgst_ctx, resumption_master_secret);
@@ -1943,3 +1957,4 @@ int tls13_recv_end_of_early_data(TLS_CONNECT *conn)
return 1;
}

View File

@@ -787,6 +787,41 @@ int x509_public_key_info_from_der(X509_KEY *x509_key, const uint8_t **in, size_t
return 1;
}
int x509_public_key_info_to_pem(const X509_KEY *a, FILE *fp)
{
uint8_t buf[512];
uint8_t *p = buf;
size_t len = 0;
if (x509_public_key_info_to_der(a, &p, &len) != 1) {
error_print();
return -1;
}
if (pem_write(fp, "PUBLIC KEY", buf, len) <= 0) {
error_print();
return -1;
}
return 1;
}
int x509_public_key_info_from_pem(X509_KEY *a, FILE *fp)
{
uint8_t buf[512];
const uint8_t *cp = buf;
size_t len;
if (pem_read(fp, "PUBLIC KEY", buf, &len, sizeof(buf)) != 1) {
error_print();
return -1;
}
if (x509_public_key_info_from_der(a, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_public_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
const uint8_t *p = d;

View File

@@ -64,6 +64,9 @@ extern int tls12_client_main(int argc, char **argv);
extern int tls12_server_main(int argc, char **argv);
extern int tls13_client_main(int argc, char **argv);
extern int tls13_server_main(int argc, char **argv);
#ifdef ENABLE_SECP256R1
extern int p256keygen_main(int argc, char **argv);
#endif
#ifdef ENABLE_LMS
extern int lmskeygen_main(int argc, char **argv);
extern int lmssign_main(int argc, char **argv);
@@ -154,6 +157,9 @@ static const char *options =
" cmsdecrypt Decrypt CMS EnvelopedData\n"
" cmssign Generate CMS SignedData\n"
" cmsverify Verify CMS SignedData\n"
#ifdef ENABLE_SECP256R1
" p256keygen Generate P-256 (secp256r1, prime256v1) keypair\n"
#endif
#ifdef ENABLE_LMS
" lmskeygen Generate LMS-SM3 (Leighton-Micali Signature) keypair\n"
" lmssign Generate LMS-SM3 signature\n"
@@ -334,6 +340,10 @@ int main(int argc, char **argv)
return tls13_client_main(argc, argv);
} else if (!strcmp(*argv, "tls13_server")) {
return tls13_server_main(argc, argv);
#ifdef ENABLE_SECP256R1
} else if (!strcmp(*argv, "p256keygen")) {
return p256keygen_main(argc, argv);
#endif
#ifdef ENABLE_LMS
} else if (!strcmp(*argv, "lmskeygen")) {
return lmskeygen_main(argc, argv);

114
tools/p256keygen.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* 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 <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/mem.h>
#include <gmssl/x509_key.h>
static const char *usage = "-pass str [-out pem] [-pubout pem]\n";
static const char *options =
"Options\n"
"\n"
" -pass pass Password to encrypt the private key\n"
" -out pem Output password-encrypted PKCS #8 private key in PEM format\n"
" -pubout pem Output public key in PEM format\n"
"\n"
"Examples\n"
"\n"
" $ gmssl p256keygen -pass P@ssw0rd -out p256.pem\n"
" $ gmssl p256keygen -pass P@ssw0rd -out p256.pem -pubout p256pub.pem\n"
"\n";
int p256keygen_main(int argc, char **argv)
{
int ret = 1;
char *prog = argv[0];
char *pass = NULL;
char *outfile = NULL;
char *puboutfile = NULL;
FILE *outfp = stdout;
FILE *puboutfp = stdout;
int curve_oid = OID_secp256r1;
X509_KEY key;
argc--;
argv++;
if (argc < 1) {
fprintf(stderr, "usage: gmssl %s %s\n", prog, usage);
return 1;
}
while (argc > 0) {
if (!strcmp(*argv, "-help")) {
printf("usage: gmssl %s %s\n", prog, usage);
printf("%s\n", options);
ret = 0;
goto end;
} else if (!strcmp(*argv, "-pass")) {
if (--argc < 1) goto bad;
pass = *(++argv);
} else if (!strcmp(*argv, "-out")) {
if (--argc < 1) goto bad;
outfile = *(++argv);
if (!(outfp = fopen(outfile, "wb"))) {
fprintf(stderr, "gmssl %s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
goto end;
}
} else if (!strcmp(*argv, "-pubout")) {
if (--argc < 1) goto bad;
puboutfile = *(++argv);
if (!(puboutfp = fopen(puboutfile, "wb"))) {
fprintf(stderr, "gmssl %s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
goto end;
}
} else {
fprintf(stderr, "gmssl %s: illegal option '%s'\n", prog, *argv);
goto end;
bad:
fprintf(stderr, "gmssl %s: `%s` option value missing\n", prog, *argv);
goto end;
}
argc--;
argv++;
}
if (!pass) {
fprintf(stderr, "gmssl %s: `-pass` option required\n", prog);
goto end;
}
if (x509_key_generate(&key, OID_ec_public_key, &curve_oid, sizeof(curve_oid)) != 1) {
fprintf(stderr, "gmssl %s: inner failure\n", prog);
return -1;
}
if (x509_private_key_info_encrypt_to_pem(&key, pass, outfp) != 1) {
fprintf(stderr, "gmssl %s: inner failure\n", prog);
return -1;
}
if (x509_public_key_info_to_pem(&key, puboutfp) != 1) {
fprintf(stderr, "gmssl %s: inner failure\n", prog);
goto end;
}
ret = 0;
end:
gmssl_secure_clear(&key, sizeof(key));
if (outfile && outfp) fclose(outfp);
if (puboutfile && puboutfp) fclose(puboutfp);
return ret;
}

View File

@@ -58,8 +58,11 @@ static char *usage =
"\n"
"Examples\n"
"\n"
" gmssl sm2keygen -pass P@ssw0rd -out key.pem\n"
" gmssl reqgen -CN www.gmssl.org -key key.pem -pass P@ssw0rd -out req.pem\n"
" gmssl sm2keygen -pass P@ssw0rd -out sm2key.pem\n"
" gmssl reqgen -CN www.gmssl.org -key sm2key.pem -pass P@ssw0rd -out sm2req.pem\n"
"\n"
" gmssl p256keygen -pass P@ssw0rd -out p256key.pem\n"
" gmssl reqgen -CN www.gmssl.org -key p256key.pem -pass P@ssw0rd -out p256req.pem\n"
"\n";

View File

@@ -365,9 +365,8 @@ bad:
error_print();
return -1;
}
error_print();
tls13_ctx_set_psk_key_exchange_modes(&ctx, psk_ke, psk_dhe_ke);
}
@@ -411,7 +410,6 @@ bad:
if (sess_in) {
FILE *sess_infp;
int enable_psk = 0;
int psk_ret = 1;
if (!(sess_infp = fopen(sess_in, "rb"))) {
@@ -431,7 +429,7 @@ bad:
// 客户端是否发送pre_shared_key是由什么决定的需要显式的支持吗
// 我觉得应该是不需要的因为如果设置了psk_key_exchange_mode那么自然要发送pre_shared_key
tls13_enable_pre_shared_key(&conn, enable_psk);
tls13_enable_pre_shared_key(&conn, 1);
}
if (sess_out) {

View File

@@ -19,6 +19,19 @@
#include <gmssl/error.h>
/*
如果采用PSK模式并且是外部密钥那么意味着每个预置密钥关联一个cipher_suite
那么ClientHello中的cipher_suites应该是这些套件的集合
但是ClientHello也可能支持PSK之外的套件因此最终是常规cipher_suite + psk_cipher_suite的合集
我们需要多组证书,也就是 -cert -key -pass 构成一组,我们可以用一个数组把这些放到一起
*/
static const char *options = "[-port num] -cert file -key file -pass str [-cacert file]";
static const char *help =
@@ -59,32 +72,34 @@ static const char *help =
"\n"
"Examples\n"
"\n"
" gmssl sm2keygen -pass 1234 -out rootcakey.pem\n"
" gmssl sm2keygen -pass 1234 -out sm2rootcakey.pem\n"
" gmssl certgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN ROOTCA -days 3650 \\\n"
" -key rootcakey.pem -pass 1234 -out rootcacert.pem \\\n"
" -key sm2rootcakey.pem -pass 1234 -out sm2rootcacert.pem \\\n"
" -key_usage keyCertSign -key_usage cRLSign -ca\n"
"\n"
" gmssl sm2keygen -pass 1234 -out cakey.pem\n"
" gmssl sm2keygen -pass 1234 -out sm2cakey.pem\n"
" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN \"Sub CA\" \\\n"
" -key cakey.pem -pass 1234 -out careq.pem\n"
" gmssl reqsign -in careq.pem -days 365 -key_usage keyCertSign -cacert rootcacert.pem -key rootcakey.pem -pass 1234 \\\n"
" -out cacert.pem -ca -path_len_constraint 0\n"
" -key sm2cakey.pem -pass 1234 -out sm2careq.pem\n"
" gmssl reqsign -in sm2careq.pem -days 365 -key_usage keyCertSign -cacert rootcacert.pem -key rootcakey.pem -pass 1234 \\\n"
" -out sm2cacert.pem -ca -path_len_constraint 0\n"
"\n"
" gmssl sm2keygen -pass 1234 -out signkey.pem\n"
" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -key signkey.pem -pass 1234 -out signreq.pem\n"
" gmssl reqsign -in signreq.pem -days 365 -key_usage digitalSignature -cacert cacert.pem -key cakey.pem -pass 1234 -out signcert.pem\n"
" gmssl sm2keygen -pass 1234 -out sm2signkey.pem\n"
" gmssl reqgen -C CN -ST Beijing -L Haidian -O PKU -OU CS -CN localhost -key sm2signkey.pem -pass 1234 -out sm2signreq.pem\n"
" gmssl reqsign -in sm2signreq.pem -days 365 -key_usage digitalSignature -cacert sm2cacert.pem -key sm2cakey.pem -pass 1234 -out sm2signcert.pem\n"
"\n"
" cat signcert.pem > certs.pem\n"
" cat cacert.pem >> certs.pem\n"
" cat sm2signcert.pem > sm2certs.pem\n"
" cat sm2cacert.pem >> sm2certs.pem\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cert certs.pem -key signkey.pem -pass 1234 -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacert.pem -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n"
" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cert certs.pem -key signkey.pem -pass 1234 \\\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n"
" -supported_group sm2p256v1 -supported_group prime256v1 \\\n"
" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert rootcacert.pem \\\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -cipher_suite TLS_AES_128_GCM_SHA256 \\\n"
" -supported_group sm2p256v1 -supported_group prime256v1 \\\n"
" -sig_alg sm2sig_sm3 -sig_alg ecdsa_secp256r1_sha256 \\\n"
@@ -95,23 +110,31 @@ static const char *help =
" -post_handshake_auth \\\n"
" -ct\n"
"\n"
"\n"
" TICKET_KEY=11223344556677881122334455667788\n"
" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n"
" -new_session_ticket 2 -ticket_key $TICKET_KEY\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cacert sm2rootcacert.pem \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 -sig_alg sm2sig_sm3 \\\n"
" -sess_out session.bin\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cert sm2certs.pem -key sm2signkey.pem -pass 1234 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n"
" -psk_dhe_ke -ticket_key $TICKET_KEY\n"
"\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 \\\n"
" -cipher_suite TLS_SM4_GCM_SM3 -supported_group sm2p256v1 \\\n"
" -psk_dhe_ke -sess_in session.bin\n"
"\n"
"\n"
" PSK=1122334455667788112233445566778811223344556677881122334455667788\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n"
" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 \\\n"
" -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data early_data.txt\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -new_session_ticket 2\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_dhe_ke -supported_group sm2p256v1 -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_dhe_ke -supported_group sm2p256v1 -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -early_data early_data.txt\n"
"\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -supported_group sm2p256v1 -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -new_session_ticket 2 -ticket_key $TICKET_KEY\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_dhe_ke -supported_group sm2p256v1 -psk_identity 001 -psk_cipher_suite TLS_SM4_GCM_SM3 -psk_key $PSK -sess_out session.bin\n"
" sudo gmssl tls13_server -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -ticket_key $TICKET_KEY\n"
" gmssl tls13_client -host 127.0.0.1 -port 4430 -cipher_suite TLS_SM4_GCM_SM3 -psk_ke -sess_in session.bin\n"
"\n";
int tls13_server_main(int argc , char **argv)
@@ -122,6 +145,17 @@ int tls13_server_main(int argc , char **argv)
char *certfile = NULL;
char *keyfile = NULL;
char *pass = NULL;
char *certfiles[4];
char *keyfiles[sizeof(certfiles)/sizeof(certfiles[0])];
char *passes[sizeof(certfiles)/sizeof(certfiles[0])];
size_t certfiles_cnt = 0;
size_t keyfiles_cnt = 0;
size_t passes_cnt = 0;
char *cacertfile = NULL;
int server_ciphers[] = { TLS_cipher_sm4_gcm_sm3, };
TLS_CTX ctx;
@@ -168,6 +202,9 @@ int tls13_server_main(int argc , char **argv)
int sig_algs[4];
size_t sig_algs_cnt = 0;
size_t i;
argc--;
argv++;
@@ -184,15 +221,37 @@ int tls13_server_main(int argc , char **argv)
} else if (!strcmp(*argv, "-port")) {
if (--argc < 1) goto bad;
port = atoi(*(++argv));
} else if (!strcmp(*argv, "-cert")) {
if (--argc < 1) goto bad;
certfile = *(++argv);
if (certfiles_cnt >= sizeof(certfiles)/sizeof(certfiles[0])) {
error_print();
return -1;
}
certfiles[certfiles_cnt++] = certfile;
} else if (!strcmp(*argv, "-key")) {
if (--argc < 1) goto bad;
keyfile = *(++argv);
if (keyfiles_cnt >= sizeof(keyfiles)/sizeof(keyfiles[0])) {
error_print();
return -1;
}
keyfiles[keyfiles_cnt++] = keyfile;
} else if (!strcmp(*argv, "-pass")) {
if (--argc < 1) goto bad;
pass = *(++argv);
if (passes_cnt >= sizeof(passes)/sizeof(passes[0])) {
error_print();
return -1;
}
passes[passes_cnt++] = pass;
} else if (!strcmp(*argv, "-cacert")) {
if (--argc < 1) goto bad;
cacertfile = *(++argv);
@@ -286,6 +345,11 @@ bad:
argv++;
}
if (certfiles_cnt != keyfiles_cnt || keyfiles_cnt != passes_cnt) {
error_print();
return -1;
}
/*
if (!cipher_suites_cnt) {
error_print();
@@ -311,6 +375,16 @@ bad:
goto end;
}
for (i = 0; i < certfiles_cnt; i++) {
fprintf(stderr, "add_certificate_chain_and_key\n");
if (tls_ctx_add_certificate_chain_and_key(&ctx, certfiles[i], keyfiles[i], passes[i]) != 1) {
error_print();
return -1;
}
}
/*
if (certfile) {
if (!keyfile) {
fprintf(stderr, "%s: '-key' option required\n", prog);
@@ -325,6 +399,7 @@ bad:
return -1;
}
}
*/
if (supported_groups_cnt > 0) {
if (tls_ctx_set_supported_groups(&ctx, supported_groups, supported_groups_cnt) != 1) {
@@ -355,12 +430,13 @@ bad:
}
if (new_session_ticket < 0) {
error_print();
fprintf(stderr, "%s: '-ticket_key' is required by '-new_session_ticket'\n", prog);
return -1;
}
if (new_session_ticket > 0) {
if (!ticket_key) {
error_print();
return -1;
}
if (tls13_ctx_enable_new_session_ticket(&ctx, new_session_ticket) != 1) {
@@ -482,6 +558,51 @@ restart:
return -1;
}
for (;;) {
fd_set fds;
size_t sentlen;
FD_ZERO(&fds);
// listen socket
FD_SET(conn.sock, &fds);
// 等待阻塞
if (select((int)(conn.sock + 1), // In WinSock2, select() ignore the this arg
&fds, NULL, NULL, NULL) < 0) {
fprintf(stderr, "%s: select failed\n", prog);
goto end;
}
if (FD_ISSET(conn.sock, &fds)) {
for (;;) {
memset(buf, 0, sizeof(buf));
if (tls13_recv(&conn, (uint8_t *)buf, sizeof(buf), &len) != 1) {
goto end;
}
fwrite(buf, 1, len, stdout);
fflush(stdout);
// FIXME: change tls13_recv API
if (conn.datalen == 0) {
break;
}
}
fprintf(stderr, ">>>>>>>> send back\n");
if (tls13_send(&conn, (uint8_t *)buf, len, &sentlen) != 1) {
fprintf(stderr, "%s: send error\n", prog);
goto end;
}
}
}
for (;;) {
int rv;