Update TLS SCT

This commit is contained in:
Zhi Guan
2026-06-10 23:44:31 +08:00
parent 79c6947ee9
commit b48f2c3772
4 changed files with 77 additions and 40 deletions

View File

@@ -24,21 +24,6 @@ extern "C" {
#endif
/*
Certificate Transparency (RFC 6962) uses TLS-style presentation language for
Signed Certificate Timestamp (SCT) objects. When SCTs are carried in an X.509
or OCSP extension, the extension value is an ASN.1 OCTET STRING whose contents
are the TLS-serialized SignedCertificateTimestampList.
id-ct OBJECT IDENTIFIER ::= { 1 3 6 1 4 1 11129 2 4 }
id-ct-precertificate-scts OBJECT IDENTIFIER ::= { id-ct 2 }
ExtnValue contents ::=
SignedCertificateTimestampList
*/
enum {
SCT_version_v1 = 0,
};
@@ -139,11 +124,6 @@ int signed_certificate_timestamp_verify(const uint8_t *sct, size_t sct_len,
X509_KEY *key, const DIGEST *digest);
/*
在验证sct_list的时候我们需要提供一组公钥的信息包括X509_KEY, Key_hash, URL , description 这三个是最重要的了
*/
typedef struct {
X509_KEY log_key;
uint8_t log_id[32];

View File

@@ -22,6 +22,7 @@
#include <gmssl/block_cipher.h>
#include <gmssl/socket.h>
#include <gmssl/x509_key.h>
#include <gmssl/sct.h>
#ifdef __cplusplus
@@ -843,6 +844,9 @@ typedef struct {
int signed_certificate_timestamp;
uint8_t signed_certificate_timestamp_lists[512]; // list of uint16array
size_t signed_certificate_timestamp_lists_len;
const CT_LOG_INFO *ct_logs;
size_t ct_logs_cnt;
size_t ct_at_least;
// 35. session_ticket
// session_ticket only supported in tls12
@@ -1878,11 +1882,16 @@ int tls_process_signature_algorithms(const uint8_t *ext_data, size_t ext_datalen
// signed_certificate_timestamp response is set by tls_ctx_add_certificate_list_and_key()
int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx, int enable); // 这里enable的是什么是否请求吗
int tls_enable_signed_certificate_timestamp(TLS_CONNECT *conn, int enable);
int tls_ctx_set_ct_logs(TLS_CTX *ctx, const CT_LOG_INFO *ct_logs,
size_t ct_logs_cnt, size_t at_least);
// 客户端需要一组SCT服务器的公钥列表才能够去验证SCT我们假定这个公钥列表在CTX中
int tls13_signed_certificate_timestamp_verify(const uint8_t *sct_list, size_t sct_list_len);
int tls13_signed_certificate_timestamp_verify(const uint8_t *sct_list, size_t sct_list_len,
int entry_type, const uint8_t issuer_key_hash[SCT_ISSUER_KEY_HASH_SIZE],
const uint8_t *entry, size_t entry_len,
const CT_LOG_INFO *ct_logs, size_t ct_logs_cnt, size_t at_least);
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,

View File

@@ -5881,6 +5881,8 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn)
size_t leaf_status_request_ocsp_response_len;
const uint8_t *leaf_signed_certificate_timestamp;
size_t leaf_signed_certificate_timestamp_len;
const uint8_t *cert;
size_t certlen;
const int *signature_algorithms_cert = NULL;
size_t signature_algorithms_cert_cnt = 0;
@@ -5996,9 +5998,18 @@ int tls13_recv_server_certificate(TLS_CONNECT *conn)
}
// signed_certificate_timestamp
if (leaf_signed_certificate_timestamp) {
if (x509_certs_get_cert_by_index(conn->peer_cert_chain,
conn->peer_cert_chain_len, 0, &cert, &certlen) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
if (tls13_signed_certificate_timestamp_verify(
leaf_signed_certificate_timestamp,
leaf_signed_certificate_timestamp_len) != 1) {
leaf_signed_certificate_timestamp_len,
SCT_log_entry_type_x509_entry, NULL, cert, certlen,
conn->ctx->ct_logs, conn->ctx->ct_logs_cnt,
conn->ctx->ct_at_least) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_bad_certificate);
return -1;
@@ -8215,6 +8226,8 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn)
size_t status_request_ocsp_response_len;
const uint8_t *signed_certificate_timestamp = NULL;
size_t signed_certificate_timestamp_len;
const uint8_t *cert;
size_t certlen;
const int *signature_algorithms_cert = NULL;
size_t signature_algorithms_cert_cnt = 0;
@@ -8333,8 +8346,17 @@ int tls13_recv_client_certificate(TLS_CONNECT *conn)
}
// signed_certificate_timestamp
if (signed_certificate_timestamp) {
if (x509_certs_get_cert_by_index(conn->peer_cert_chain,
conn->peer_cert_chain_len, 0, &cert, &certlen) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_bad_certificate);
return -1;
}
if (tls13_signed_certificate_timestamp_verify(
signed_certificate_timestamp, signed_certificate_timestamp_len) != 1) {
signed_certificate_timestamp, signed_certificate_timestamp_len,
SCT_log_entry_type_x509_entry, NULL, cert, certlen,
conn->ctx->ct_logs, conn->ctx->ct_logs_cnt,
conn->ctx->ct_at_least) != 1) {
error_print();
tls13_send_alert(conn, TLS_alert_bad_certificate);
return -1;

View File

@@ -22,6 +22,7 @@
#include <gmssl/pem.h>
#include <gmssl/mem.h>
#include <gmssl/tls.h>
#include <gmssl/sct.h>
/*
@@ -38,8 +39,10 @@ Certificate.certificate_list.CertificateEntry.exts.signed_certificate_timestamp
uint64 timestamp;
opaque signature<0..2^16-1>;
} SignedCertificateTimestamp;
// SignedCertificateTimestamp 的格式不对
*/
/*
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)
@@ -71,6 +74,7 @@ int tls_signed_certificate_timestamp_entry_from_bytes(const uint8_t **key_id,
}
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)
@@ -101,8 +105,14 @@ int tls_signed_certificate_timestamp_print(FILE *fp, int fmt, int ind, const uin
{
const uint8_t *sct_list;
size_t sct_list_len;
size_t i = 0;
if (tls_uint16array_from_bytes(&sct_list, &sct_list_len, &d, &dlen) != 1) {
if (!fp || !d) {
error_print();
return -1;
}
if (tls_uint16array_from_bytes(&sct_list, &sct_list_len, &d, &dlen) != 1
|| dlen) {
error_print();
return -1;
}
@@ -113,24 +123,18 @@ int tls_signed_certificate_timestamp_print(FILE *fp, int fmt, int ind, const uin
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;
const uint8_t *sct;
size_t sct_len;
char label[64];
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) {
if (tls_uint16array_from_bytes(&sct, &sct_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) {
snprintf(label, sizeof(label), "SignedCertificateTimestamp[%zu]", i++);
if (signed_certificate_timestamp_print(fp, fmt, ind, label,
sct, sct_len) != 1) {
error_print();
return -1;
}
@@ -158,8 +162,30 @@ int tls_ctx_enable_signed_certificate_timestamp(TLS_CTX *ctx, int enable)
return 1;
}
int tls13_signed_certificate_timestamp_verify(const uint8_t *sct_list, size_t sct_list_len)
int tls_ctx_set_ct_logs(TLS_CTX *ctx, const CT_LOG_INFO *ct_logs,
size_t ct_logs_cnt, size_t at_least)
{
error_print();
if (!ctx || (ct_logs_cnt && !ct_logs) || at_least > ct_logs_cnt) {
error_print();
return -1;
}
ctx->ct_logs = ct_logs;
ctx->ct_logs_cnt = ct_logs_cnt;
ctx->ct_at_least = at_least;
return 1;
}
int tls13_signed_certificate_timestamp_verify(const uint8_t *sct_list, size_t sct_list_len,
int entry_type, const uint8_t issuer_key_hash[SCT_ISSUER_KEY_HASH_SIZE],
const uint8_t *entry, size_t entry_len,
const CT_LOG_INFO *ct_logs, size_t ct_logs_cnt, size_t at_least)
{
if (!ct_logs_cnt) {
return 1;
}
if (!at_least) {
at_least = 1;
}
return sct_list_verify(sct_list, sct_list_len, entry_type,
issuer_key_hash, entry, entry_len, ct_logs, ct_logs_cnt, at_least);
}