mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-19 19:33:38 +08:00
Add trusted_ca_keys to TLS1.2/TLCP
This commit is contained in:
@@ -841,6 +841,8 @@ typedef struct {
|
|||||||
|
|
||||||
// 3. trusted_ca_keys
|
// 3. trusted_ca_keys
|
||||||
int trusted_ca_keys;
|
int trusted_ca_keys;
|
||||||
|
uint8_t trusted_authorities[512];
|
||||||
|
size_t trusted_authorities_len;
|
||||||
|
|
||||||
// 5. status_request
|
// 5. status_request
|
||||||
int status_request; // if send in ClientHello, CertificateRequest
|
int status_request; // if send in ClientHello, CertificateRequest
|
||||||
@@ -946,6 +948,7 @@ int tls_ctx_add_certificate_list_and_key(TLS_CTX *ctx, const char *chainfile,
|
|||||||
|
|
||||||
|
|
||||||
int tls_ctx_enable_verbose(TLS_CTX *ctx, int enable);
|
int tls_ctx_enable_verbose(TLS_CTX *ctx, int enable);
|
||||||
|
int tls_ctx_enable_trusted_ca_keys(TLS_CTX *ctx, int enable);
|
||||||
|
|
||||||
|
|
||||||
// KeyUpdate
|
// KeyUpdate
|
||||||
@@ -1174,6 +1177,8 @@ typedef struct {
|
|||||||
|
|
||||||
// 3. trusted_ca_keys
|
// 3. trusted_ca_keys
|
||||||
int trusted_ca_keys;
|
int trusted_ca_keys;
|
||||||
|
uint8_t trusted_authorities[512];
|
||||||
|
size_t trusted_authorities_len;
|
||||||
|
|
||||||
// 5. status_request
|
// 5. status_request
|
||||||
int status_request;
|
int status_request;
|
||||||
@@ -1688,12 +1693,35 @@ enum {
|
|||||||
TLS_name_type_preserved_max = 255,
|
TLS_name_type_preserved_max = 255,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TLS_trusted_authority_pre_agreed = 0,
|
||||||
|
TLS_trusted_authority_key_sha1_hash = 1,
|
||||||
|
TLS_trusted_authority_x509_name = 2,
|
||||||
|
TLS_trusted_authority_cert_sha1_hash = 3,
|
||||||
|
TLS_trusted_authority_reserved_max = 255,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#define tls_ext_data(ext) ((ext) + 4)
|
#define tls_ext_data(ext) ((ext) + 4)
|
||||||
|
|
||||||
int tls_ext_to_bytes(int ext_type, const uint8_t *ext_data, size_t ext_datalen,
|
int tls_ext_to_bytes(int ext_type, const uint8_t *ext_data, size_t ext_datalen,
|
||||||
uint8_t **out, size_t *outlen);
|
uint8_t **out, size_t *outlen);
|
||||||
|
|
||||||
|
const char *tls_trusted_authority_type_name(int type);
|
||||||
|
int tls_trusted_authority_to_bytes(int type, const uint8_t *data, size_t datalen,
|
||||||
|
uint8_t **out, size_t *outlen);
|
||||||
|
int tls_trusted_authority_from_bytes(int *type, const uint8_t **data, size_t *datalen,
|
||||||
|
const uint8_t **in, size_t *inlen);
|
||||||
|
int tls_trusted_authorities_to_bytes(const uint8_t *authorities, size_t authorities_len,
|
||||||
|
uint8_t **out, size_t *outlen);
|
||||||
|
int tls_trusted_authorities_from_bytes(const uint8_t **authorities, size_t *authorities_len,
|
||||||
|
const uint8_t *data, size_t datalen);
|
||||||
|
int tls_trusted_ca_keys_ext_to_bytes(const uint8_t *authorities, size_t authorities_len,
|
||||||
|
uint8_t **out, size_t *outlen);
|
||||||
|
int tls_trusted_authorities_from_ca_names(uint8_t *authorities, size_t *authorities_len, size_t maxlen,
|
||||||
|
const uint8_t *ca_names, size_t ca_names_len);
|
||||||
|
int tls_trusted_authorities_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
30
src/tlcp.c
30
src/tlcp.c
@@ -329,9 +329,12 @@ int tlcp_send_client_hello(TLS_CONNECT *conn)
|
|||||||
|
|
||||||
// trusted_ca_keys
|
// trusted_ca_keys
|
||||||
if (conn->ctx->trusted_ca_keys) {
|
if (conn->ctx->trusted_ca_keys) {
|
||||||
|
if (tls_trusted_ca_keys_ext_to_bytes(conn->ctx->trusted_authorities,
|
||||||
|
conn->ctx->trusted_authorities_len, &pexts, &extslen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// status_request (hint only)
|
// status_request (hint only)
|
||||||
if (conn->status_request) {
|
if (conn->status_request) {
|
||||||
@@ -1315,8 +1318,9 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
// extensions
|
// extensions
|
||||||
const uint8_t *server_name = NULL;
|
const uint8_t *server_name = NULL;
|
||||||
size_t server_name_len = 0;
|
size_t server_name_len = 0;
|
||||||
const uint8_t *trusted_ca_keys = NULL;
|
int trusted_ca_keys = 0;
|
||||||
size_t trusted_ca_keys_len = 0;
|
const uint8_t *trusted_authorities = NULL;
|
||||||
|
size_t trusted_authorities_len = 0;
|
||||||
const uint8_t *status_request = NULL;
|
const uint8_t *status_request = NULL;
|
||||||
size_t status_request_len = 0;
|
size_t status_request_len = 0;
|
||||||
const uint8_t *supported_groups = NULL;
|
const uint8_t *supported_groups = NULL;
|
||||||
@@ -1434,8 +1438,13 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
tls13_send_alert(conn, TLS_alert_illegal_parameter);
|
tls13_send_alert(conn, TLS_alert_illegal_parameter);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
trusted_ca_keys = ext_data;
|
if (tls_trusted_authorities_from_bytes(&trusted_authorities,
|
||||||
trusted_ca_keys_len = ext_datalen;
|
&trusted_authorities_len, ext_data, ext_datalen) != 1) {
|
||||||
|
error_print();
|
||||||
|
tls13_send_alert(conn, TLS_alert_decode_error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
trusted_ca_keys = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TLS_extension_status_request:
|
case TLS_extension_status_request:
|
||||||
@@ -1500,6 +1509,19 @@ int tlcp_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trusted_ca_keys) {
|
||||||
|
conn->trusted_ca_keys = 1;
|
||||||
|
if (trusted_authorities_len > sizeof(conn->trusted_authorities)) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (trusted_authorities_len) {
|
||||||
|
memcpy(conn->trusted_authorities, trusted_authorities, trusted_authorities_len);
|
||||||
|
}
|
||||||
|
conn->trusted_authorities_len = trusted_authorities_len;
|
||||||
|
}
|
||||||
|
|
||||||
if (application_layer_protocol_negotiation) {
|
if (application_layer_protocol_negotiation) {
|
||||||
if (!conn->ctx->alpn_protocols_cnt) {
|
if (!conn->ctx->alpn_protocols_cnt) {
|
||||||
error_print();
|
error_print();
|
||||||
|
|||||||
15
src/tls.c
15
src/tls.c
@@ -2507,6 +2507,11 @@ int tls_ctx_set_ca_certificates(TLS_CTX *ctx, const char *cacertsfile, int depth
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
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;
|
ctx->verify_depth = depth;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2522,6 +2527,16 @@ int tls_ctx_enable_verbose(TLS_CTX *ctx, int enable)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tls_ctx_enable_trusted_ca_keys(TLS_CTX *ctx, int enable)
|
||||||
|
{
|
||||||
|
if (!ctx) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ctx->trusted_ca_keys = enable ? 1 : 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int tls_ctx_enable_certificate_request(TLS_CTX *ctx, int enable)
|
int tls_ctx_enable_certificate_request(TLS_CTX *ctx, int enable)
|
||||||
{
|
{
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
|
|||||||
61
src/tls12.c
61
src/tls12.c
@@ -868,6 +868,15 @@ int tls_send_client_hello(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trusted_ca_keys
|
||||||
|
if (conn->ctx->trusted_ca_keys) {
|
||||||
|
if (tls_trusted_ca_keys_ext_to_bytes(conn->ctx->trusted_authorities,
|
||||||
|
conn->ctx->trusted_authorities_len, &pexts, &extslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// server_name
|
// server_name
|
||||||
if (conn->server_name) {
|
if (conn->server_name) {
|
||||||
if (tls_server_name_ext_to_bytes(conn->host_name, conn->host_name_len, &pexts, &extslen) != 1) {
|
if (tls_server_name_ext_to_bytes(conn->host_name, conn->host_name_len, &pexts, &extslen) != 1) {
|
||||||
@@ -1275,6 +1284,9 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
size_t signature_algorithms_len = 0;
|
size_t signature_algorithms_len = 0;
|
||||||
const uint8_t *signature_algorithms_cert = NULL;
|
const uint8_t *signature_algorithms_cert = NULL;
|
||||||
size_t signature_algorithms_cert_len = 0;
|
size_t signature_algorithms_cert_len = 0;
|
||||||
|
int trusted_ca_keys = 0;
|
||||||
|
const uint8_t *trusted_authorities = NULL;
|
||||||
|
size_t trusted_authorities_len = 0;
|
||||||
const uint8_t *server_name = NULL;
|
const uint8_t *server_name = NULL;
|
||||||
size_t server_name_len = 0;
|
size_t server_name_len = 0;
|
||||||
const uint8_t *renegotiation_info = NULL;
|
const uint8_t *renegotiation_info = NULL;
|
||||||
@@ -1352,7 +1364,6 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
case TLS_extension_supported_groups:
|
case TLS_extension_supported_groups:
|
||||||
case TLS_extension_signature_algorithms:
|
case TLS_extension_signature_algorithms:
|
||||||
case TLS_extension_signature_algorithms_cert:
|
case TLS_extension_signature_algorithms_cert:
|
||||||
case TLS_extension_server_name:
|
|
||||||
case TLS_extension_renegotiation_info:
|
case TLS_extension_renegotiation_info:
|
||||||
if (!ext_data) {
|
if (!ext_data) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -1360,6 +1371,9 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TLS_extension_trusted_ca_keys:
|
||||||
|
case TLS_extension_server_name:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ext_type) {
|
switch (ext_type) {
|
||||||
@@ -1399,6 +1413,20 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
signature_algorithms_cert = ext_data;
|
signature_algorithms_cert = ext_data;
|
||||||
signature_algorithms_cert_len = ext_datalen;
|
signature_algorithms_cert_len = ext_datalen;
|
||||||
break;
|
break;
|
||||||
|
case TLS_extension_trusted_ca_keys:
|
||||||
|
if (trusted_ca_keys) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_illegal_parameter);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_trusted_authorities_from_bytes(&trusted_authorities,
|
||||||
|
&trusted_authorities_len, ext_data, ext_datalen) != 1) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_decode_error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
trusted_ca_keys = 1;
|
||||||
|
break;
|
||||||
case TLS_extension_server_name:
|
case TLS_extension_server_name:
|
||||||
if (server_name) {
|
if (server_name) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -1465,6 +1493,19 @@ int tls_recv_client_hello(TLS_CONNECT *conn)
|
|||||||
conn->ec_point_formats = 1;
|
conn->ec_point_formats = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trusted_ca_keys) {
|
||||||
|
conn->trusted_ca_keys = 1;
|
||||||
|
if (trusted_authorities_len > sizeof(conn->trusted_authorities)) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_internal_error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (trusted_authorities_len) {
|
||||||
|
memcpy(conn->trusted_authorities, trusted_authorities, trusted_authorities_len);
|
||||||
|
}
|
||||||
|
conn->trusted_authorities_len = trusted_authorities_len;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ret = tls12_select_common_cipher_suites(cipher_suites, cipher_suites_len,
|
if ((ret = tls12_select_common_cipher_suites(cipher_suites, cipher_suites_len,
|
||||||
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt,
|
conn->ctx->cipher_suites, conn->ctx->cipher_suites_cnt,
|
||||||
common_cipher_suites, &common_cipher_suites_cnt,
|
common_cipher_suites, &common_cipher_suites_cnt,
|
||||||
@@ -1636,6 +1677,14 @@ int tls_send_server_hello(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trusted_ca_keys
|
||||||
|
if (conn->trusted_ca_keys) {
|
||||||
|
if (tls_ext_to_bytes(TLS_extension_trusted_ca_keys, NULL, 0, &pexts, &extslen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// renegotiation_info
|
// renegotiation_info
|
||||||
if (conn->secure_renegotiation) {
|
if (conn->secure_renegotiation) {
|
||||||
uint8_t ext_data[1] = { 0 };
|
uint8_t ext_data[1] = { 0 };
|
||||||
@@ -1695,6 +1744,7 @@ int tls_recv_server_hello(TLS_CONNECT *conn)
|
|||||||
const uint8_t *ec_point_formats = NULL;
|
const uint8_t *ec_point_formats = NULL;
|
||||||
size_t ec_point_formats_len = 0;
|
size_t ec_point_formats_len = 0;
|
||||||
int server_name = 0;
|
int server_name = 0;
|
||||||
|
int trusted_ca_keys = 0;
|
||||||
int renegotiation_info = 0;
|
int renegotiation_info = 0;
|
||||||
|
|
||||||
tls_trace("recv ServerHello\n");
|
tls_trace("recv ServerHello\n");
|
||||||
@@ -1787,6 +1837,15 @@ int tls_recv_server_hello(TLS_CONNECT *conn)
|
|||||||
}
|
}
|
||||||
server_name = 1;
|
server_name = 1;
|
||||||
break;
|
break;
|
||||||
|
case TLS_extension_trusted_ca_keys:
|
||||||
|
if (!conn->ctx->trusted_ca_keys || trusted_ca_keys || ext_datalen) {
|
||||||
|
error_print();
|
||||||
|
tls_send_alert(conn, TLS_alert_illegal_parameter);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
trusted_ca_keys = 1;
|
||||||
|
conn->trusted_ca_keys = 1;
|
||||||
|
break;
|
||||||
case TLS_extension_renegotiation_info:
|
case TLS_extension_renegotiation_info:
|
||||||
if ((!conn->ctx->renegotiation_info && !conn->ctx->empty_renegotiation_info_scsv)
|
if ((!conn->ctx->renegotiation_info && !conn->ctx->empty_renegotiation_info_scsv)
|
||||||
|| renegotiation_info) {
|
|| renegotiation_info) {
|
||||||
|
|||||||
305
src/tls_ext.c
305
src/tls_ext.c
@@ -62,6 +62,311 @@ int tls_ext_from_bytes(int *type, const uint8_t **data, size_t *datalen, const u
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
3. trusted_ca_keys
|
||||||
|
|
||||||
|
struct {
|
||||||
|
TrustedAuthority trusted_authorities_list<0..2^16-1>;
|
||||||
|
} TrustedAuthorities;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
IdentifierType identifier_type;
|
||||||
|
select (identifier_type) {
|
||||||
|
case pre_agreed: struct {};
|
||||||
|
case key_sha1_hash: SHA1Hash;
|
||||||
|
case x509_name: DistinguishedName;
|
||||||
|
case cert_sha1_hash: SHA1Hash;
|
||||||
|
} identifier;
|
||||||
|
} TrustedAuthority;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
pre_agreed(0), key_sha1_hash(1), x509_name(2),
|
||||||
|
cert_sha1_hash(3), (255)
|
||||||
|
} IdentifierType;
|
||||||
|
|
||||||
|
opaque DistinguishedName<1..2^16-1>;
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *tls_trusted_authority_type_name(int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case TLS_trusted_authority_pre_agreed: return "pre_agreed";
|
||||||
|
case TLS_trusted_authority_key_sha1_hash: return "key_sha1_hash";
|
||||||
|
case TLS_trusted_authority_x509_name: return "x509_name";
|
||||||
|
case TLS_trusted_authority_cert_sha1_hash: return "cert_sha1_hash";
|
||||||
|
default: return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_trusted_authority_to_bytes(int type, const uint8_t *data, size_t datalen,
|
||||||
|
uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
if (!outlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!tls_trusted_authority_type_name(type)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case TLS_trusted_authority_pre_agreed:
|
||||||
|
if (data || datalen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tls_uint8_to_bytes((uint8_t)type, out, outlen);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TLS_trusted_authority_key_sha1_hash:
|
||||||
|
case TLS_trusted_authority_cert_sha1_hash:
|
||||||
|
if (!data || datalen != 20) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tls_uint8_to_bytes((uint8_t)type, out, outlen);
|
||||||
|
tls_array_to_bytes(data, datalen, out, outlen);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TLS_trusted_authority_x509_name:
|
||||||
|
if (!data || datalen < 1 || datalen > UINT16_MAX) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tls_uint8_to_bytes((uint8_t)type, out, outlen);
|
||||||
|
tls_uint16array_to_bytes(data, datalen, out, outlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_trusted_authority_from_bytes(int *type, const uint8_t **data, size_t *datalen,
|
||||||
|
const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
uint8_t u8;
|
||||||
|
|
||||||
|
if (!type || !data || !datalen || !in || !(*in) || !inlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_uint8_from_bytes(&u8, in, inlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!tls_trusted_authority_type_name(u8)) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*type = u8;
|
||||||
|
switch (u8) {
|
||||||
|
case TLS_trusted_authority_pre_agreed:
|
||||||
|
*data = NULL;
|
||||||
|
*datalen = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TLS_trusted_authority_key_sha1_hash:
|
||||||
|
case TLS_trusted_authority_cert_sha1_hash:
|
||||||
|
if (*inlen < 20) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*data = *in;
|
||||||
|
*datalen = 20;
|
||||||
|
*in += 20;
|
||||||
|
*inlen -= 20;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TLS_trusted_authority_x509_name:
|
||||||
|
if (tls_uint16array_from_bytes(data, datalen, in, inlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*datalen < 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_trusted_authorities_to_bytes(const uint8_t *authorities, size_t authorities_len,
|
||||||
|
uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
if (!outlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!authorities && authorities_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (authorities_len > UINT16_MAX) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tls_uint16array_to_bytes(authorities, authorities_len, out, outlen);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_trusted_authorities_from_bytes(const uint8_t **authorities, size_t *authorities_len,
|
||||||
|
const uint8_t *data, size_t datalen)
|
||||||
|
{
|
||||||
|
const uint8_t *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (!authorities || !authorities_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1
|
||||||
|
|| tls_length_is_zero(datalen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*authorities = p;
|
||||||
|
*authorities_len = len;
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
int type;
|
||||||
|
const uint8_t *d;
|
||||||
|
size_t dlen;
|
||||||
|
|
||||||
|
if (tls_trusted_authority_from_bytes(&type, &d, &dlen, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (type == TLS_trusted_authority_x509_name) {
|
||||||
|
const uint8_t *name;
|
||||||
|
size_t namelen;
|
||||||
|
if (asn1_sequence_from_der(&name, &namelen, &d, &dlen) != 1
|
||||||
|
|| asn1_length_is_zero(dlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_trusted_ca_keys_ext_to_bytes(const uint8_t *authorities, size_t authorities_len,
|
||||||
|
uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
uint8_t ext_data[512];
|
||||||
|
uint8_t *p = ext_data;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (authorities_len > sizeof(ext_data) - tls_uint16_size()) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_trusted_authorities_to_bytes(authorities, authorities_len, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_ext_to_bytes(TLS_extension_trusted_ca_keys, ext_data, len, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_trusted_authorities_from_ca_names(uint8_t *authorities, size_t *authorities_len, size_t maxlen,
|
||||||
|
const uint8_t *ca_names, size_t ca_names_len)
|
||||||
|
{
|
||||||
|
uint8_t *p = authorities;
|
||||||
|
|
||||||
|
if (!authorities || !authorities_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!ca_names && ca_names_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*authorities_len = 0;
|
||||||
|
|
||||||
|
while (ca_names_len) {
|
||||||
|
const uint8_t *name;
|
||||||
|
size_t namelen;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (tls_uint16array_from_bytes(&name, &namelen, &ca_names, &ca_names_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_trusted_authority_to_bytes(TLS_trusted_authority_x509_name,
|
||||||
|
name, namelen, NULL, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*authorities_len + len > maxlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (tls_trusted_authority_to_bytes(TLS_trusted_authority_x509_name,
|
||||||
|
name, namelen, &p, authorities_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tls_trusted_authorities_print(FILE *fp, int fmt, int ind, const uint8_t *ext_data, size_t ext_datalen)
|
||||||
|
{
|
||||||
|
const uint8_t *authorities;
|
||||||
|
size_t authorities_len;
|
||||||
|
|
||||||
|
format_print(fp, fmt, ind, "trusted_authorities\n");
|
||||||
|
ind += 4;
|
||||||
|
|
||||||
|
if (tls_trusted_authorities_from_bytes(&authorities, &authorities_len, ext_data, ext_datalen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while (authorities_len) {
|
||||||
|
int type;
|
||||||
|
const uint8_t *data;
|
||||||
|
size_t datalen;
|
||||||
|
|
||||||
|
if (tls_trusted_authority_from_bytes(&type, &data, &datalen, &authorities, &authorities_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
format_print(fp, fmt, ind, "%s (%d)\n", tls_trusted_authority_type_name(type), type);
|
||||||
|
switch (type) {
|
||||||
|
case TLS_trusted_authority_pre_agreed:
|
||||||
|
break;
|
||||||
|
case TLS_trusted_authority_key_sha1_hash:
|
||||||
|
case TLS_trusted_authority_cert_sha1_hash:
|
||||||
|
format_bytes(fp, fmt, ind + 4, "sha1_hash", data, datalen);
|
||||||
|
break;
|
||||||
|
case TLS_trusted_authority_x509_name:
|
||||||
|
{
|
||||||
|
const uint8_t *name;
|
||||||
|
size_t namelen;
|
||||||
|
if (asn1_sequence_from_der(&name, &namelen, &data, &datalen) != 1
|
||||||
|
|| asn1_length_is_zero(datalen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
x509_name_print(fp, fmt, ind + 4, "DistinguishedName", name, namelen);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
11. ec_point_formats
|
11. ec_point_formats
|
||||||
|
|||||||
@@ -520,6 +520,16 @@ int tls_extension_print(FILE *fp, int type, const uint8_t *data, size_t datalen,
|
|||||||
tls_ec_point_format_name(point_form), point_form);
|
tls_ec_point_format_name(point_form), point_form);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TLS_extension_trusted_ca_keys:
|
||||||
|
if (datalen == 0) {
|
||||||
|
format_bytes(fp, format, indent, "raw_data", data, datalen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tls_trusted_authorities_print(fp, format, indent, data, datalen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TLS_extension_signature_algorithms:
|
case TLS_extension_signature_algorithms:
|
||||||
if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1
|
if (tls_uint16array_from_bytes(&p, &len, &data, &datalen) != 1
|
||||||
|| datalen
|
|| datalen
|
||||||
|
|||||||
@@ -352,6 +352,90 @@ static int test_tls_status_request_ext(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_tls_trusted_ca_keys_ext(void)
|
||||||
|
{
|
||||||
|
uint8_t name[256];
|
||||||
|
size_t namelen = 0;
|
||||||
|
uint8_t der_name[256];
|
||||||
|
uint8_t *p = der_name;
|
||||||
|
size_t der_name_len = 0;
|
||||||
|
uint8_t hash[20];
|
||||||
|
uint8_t authorities[512];
|
||||||
|
uint8_t *pa = authorities;
|
||||||
|
size_t authorities_len = 0;
|
||||||
|
uint8_t ext[512];
|
||||||
|
const uint8_t *ext_data;
|
||||||
|
size_t ext_datalen;
|
||||||
|
int ext_type;
|
||||||
|
const uint8_t *list;
|
||||||
|
size_t list_len;
|
||||||
|
const uint8_t *cp;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
memset(hash, 0x5a, sizeof(hash));
|
||||||
|
if (x509_name_set(name, &namelen, sizeof(name),
|
||||||
|
"CN", "Beijing", "Haidian", "PKU", "CS", "CA") != 1
|
||||||
|
|| asn1_sequence_to_der(name, namelen, &p, &der_name_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tls_trusted_authority_to_bytes(TLS_trusted_authority_pre_agreed,
|
||||||
|
NULL, 0, &pa, &authorities_len) != 1
|
||||||
|
|| tls_trusted_authority_to_bytes(TLS_trusted_authority_key_sha1_hash,
|
||||||
|
hash, sizeof(hash), &pa, &authorities_len) != 1
|
||||||
|
|| tls_trusted_authority_to_bytes(TLS_trusted_authority_x509_name,
|
||||||
|
der_name, der_name_len, &pa, &authorities_len) != 1
|
||||||
|
|| tls_trusted_authority_to_bytes(TLS_trusted_authority_cert_sha1_hash,
|
||||||
|
hash, sizeof(hash), &pa, &authorities_len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ext;
|
||||||
|
len = 0;
|
||||||
|
if (tls_trusted_ca_keys_ext_to_bytes(authorities, authorities_len, &p, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
cp = ext;
|
||||||
|
if (tls_ext_from_bytes(&ext_type, &ext_data, &ext_datalen, &cp, &len) != 1
|
||||||
|
|| ext_type != TLS_extension_trusted_ca_keys
|
||||||
|
|| len != 0
|
||||||
|
|| tls_trusted_authorities_from_bytes(&list, &list_len, ext_data, ext_datalen) != 1
|
||||||
|
|| list_len != authorities_len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
const uint8_t *data;
|
||||||
|
size_t datalen;
|
||||||
|
|
||||||
|
if (tls_trusted_authority_from_bytes(&type, &data, &datalen, &list, &list_len) != 1
|
||||||
|
|| type != TLS_trusted_authority_pre_agreed
|
||||||
|
|| data != NULL || datalen != 0
|
||||||
|
|| tls_trusted_authority_from_bytes(&type, &data, &datalen, &list, &list_len) != 1
|
||||||
|
|| type != TLS_trusted_authority_key_sha1_hash
|
||||||
|
|| datalen != sizeof(hash) || memcmp(data, hash, sizeof(hash)) != 0
|
||||||
|
|| tls_trusted_authority_from_bytes(&type, &data, &datalen, &list, &list_len) != 1
|
||||||
|
|| type != TLS_trusted_authority_x509_name
|
||||||
|
|| datalen != der_name_len || memcmp(data, der_name, der_name_len) != 0
|
||||||
|
|| tls_trusted_authority_from_bytes(&type, &data, &datalen, &list, &list_len) != 1
|
||||||
|
|| type != TLS_trusted_authority_cert_sha1_hash
|
||||||
|
|| datalen != sizeof(hash) || memcmp(data, hash, sizeof(hash)) != 0
|
||||||
|
|| list_len != 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tls_trusted_authorities_print(stdout, 0, 0, ext_data, ext_datalen);
|
||||||
|
printf("%s() ok\n", __FUNCTION__);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
if (test_tls_null_to_bytes() != 1) goto err;
|
if (test_tls_null_to_bytes() != 1) goto err;
|
||||||
@@ -369,6 +453,7 @@ int main(void)
|
|||||||
if (test_tls_change_cipher_spec() != 1) goto err;
|
if (test_tls_change_cipher_spec() != 1) goto err;
|
||||||
if (test_tls_application_data() != 1) goto err;
|
if (test_tls_application_data() != 1) goto err;
|
||||||
*/
|
*/
|
||||||
|
if (test_tls_trusted_ca_keys_ext() != 1) goto err;
|
||||||
if (test_tls_status_request_ext() != 1) goto err;
|
if (test_tls_status_request_ext() != 1) goto err;
|
||||||
printf("%s all tests passed\n", __FILE__);
|
printf("%s all tests passed\n", __FILE__);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ static const char *usage =
|
|||||||
" [-outcerts file]"
|
" [-outcerts file]"
|
||||||
" [-get path]"
|
" [-get path]"
|
||||||
" [-alpn str]"
|
" [-alpn str]"
|
||||||
|
" [-trusted_ca_keys]"
|
||||||
" [-quiet]";
|
" [-quiet]";
|
||||||
|
|
||||||
static const char *help =
|
static const char *help =
|
||||||
@@ -44,6 +45,7 @@ static const char *help =
|
|||||||
" -get path Send a GET request with given path of URI\n"
|
" -get path Send a GET request with given path of URI\n"
|
||||||
" -outcerts file Save server certificates to a PEM file\n"
|
" -outcerts file Save server certificates to a PEM file\n"
|
||||||
" -server_name str Send server_name (SNI) request\n"
|
" -server_name str Send server_name (SNI) request\n"
|
||||||
|
" -trusted_ca_keys Send trusted_ca_keys request\n"
|
||||||
" -alpn str Application protocol name, may appear multiple times, higher priority first\n"
|
" -alpn str Application protocol name, may appear multiple times, higher priority first\n"
|
||||||
" -status_request Send status_request (OCSP Stapling) request\n"
|
" -status_request Send status_request (OCSP Stapling) request\n"
|
||||||
" -quiet Without printing any status message\n"
|
" -quiet Without printing any status message\n"
|
||||||
@@ -71,6 +73,7 @@ int tlcp_client_main(int argc, char *argv[])
|
|||||||
char *keyfile = NULL;
|
char *keyfile = NULL;
|
||||||
char *pass = NULL;
|
char *pass = NULL;
|
||||||
char *server_name = NULL;
|
char *server_name = NULL;
|
||||||
|
int trusted_ca_keys = 0;
|
||||||
char *alpn_protocols[4];
|
char *alpn_protocols[4];
|
||||||
size_t alpn_protocols_cnt = 0;
|
size_t alpn_protocols_cnt = 0;
|
||||||
int client_cert_optional = 0;
|
int client_cert_optional = 0;
|
||||||
@@ -169,6 +172,8 @@ int tlcp_client_main(int argc, char *argv[])
|
|||||||
} else if (!strcmp(*argv, "-server_name")) {
|
} else if (!strcmp(*argv, "-server_name")) {
|
||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
server_name = *(++argv);
|
server_name = *(++argv);
|
||||||
|
} else if (!strcmp(*argv, "-trusted_ca_keys")) {
|
||||||
|
trusted_ca_keys = 1;
|
||||||
} else if (!strcmp(*argv, "-alpn")) {
|
} else if (!strcmp(*argv, "-alpn")) {
|
||||||
if (alpn_protocols_cnt >= sizeof(alpn_protocols)/sizeof(alpn_protocols[0])) {
|
if (alpn_protocols_cnt >= sizeof(alpn_protocols)/sizeof(alpn_protocols[0])) {
|
||||||
fprintf(stderr, "%s: too many -alpn options\n", prog);
|
fprintf(stderr, "%s: too many -alpn options\n", prog);
|
||||||
@@ -224,6 +229,13 @@ bad:
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trusted_ca_keys) {
|
||||||
|
if (tls_ctx_enable_trusted_ca_keys(&ctx, 1) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (alpn_protocols_cnt) {
|
if (alpn_protocols_cnt) {
|
||||||
if (tls_ctx_set_application_layer_protocol_negotiation(&ctx,
|
if (tls_ctx_set_application_layer_protocol_negotiation(&ctx,
|
||||||
alpn_protocols, alpn_protocols_cnt) != 1) {
|
alpn_protocols, alpn_protocols_cnt) != 1) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ static const char *http_get =
|
|||||||
"Hostname: aaa\r\n"
|
"Hostname: aaa\r\n"
|
||||||
"\r\n\r\n";
|
"\r\n\r\n";
|
||||||
|
|
||||||
static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str]";
|
static const char *options = "-host str [-port num] [-cacert file] [-cert file -key file -pass str] [-trusted_ca_keys]";
|
||||||
|
|
||||||
static const char *help =
|
static const char *help =
|
||||||
"Options\n"
|
"Options\n"
|
||||||
@@ -40,6 +40,7 @@ static const char *help =
|
|||||||
" -pass str Password to decrypt private key\n"
|
" -pass str Password to decrypt private key\n"
|
||||||
" -client_cert_optional Allow client send empty Certificate\n"
|
" -client_cert_optional Allow client send empty Certificate\n"
|
||||||
" -server_name str Send server_name (SNI) request\n"
|
" -server_name str Send server_name (SNI) request\n"
|
||||||
|
" -trusted_ca_keys Send trusted_ca_keys request\n"
|
||||||
" -renegotiation_info Send renegotiation_info extension\n"
|
" -renegotiation_info Send renegotiation_info extension\n"
|
||||||
" -renegotiation_info_scsv\n"
|
" -renegotiation_info_scsv\n"
|
||||||
" Send TLS_EMPTY_RENEGOTIATION_INFO_SCSV\n"
|
" Send TLS_EMPTY_RENEGOTIATION_INFO_SCSV\n"
|
||||||
@@ -67,6 +68,7 @@ int tls12_client_main(int argc, char *argv[])
|
|||||||
char *pass = NULL;
|
char *pass = NULL;
|
||||||
int client_cert_optional = 0;
|
int client_cert_optional = 0;
|
||||||
char *server_name = NULL;
|
char *server_name = NULL;
|
||||||
|
int trusted_ca_keys = 0;
|
||||||
int renegotiation_info = 0;
|
int renegotiation_info = 0;
|
||||||
int empty_renegotiation_info_scsv = 0;
|
int empty_renegotiation_info_scsv = 0;
|
||||||
TLS_CTX ctx;
|
TLS_CTX ctx;
|
||||||
@@ -160,6 +162,8 @@ int tls12_client_main(int argc, char *argv[])
|
|||||||
} else if (!strcmp(*argv, "-server_name")) {
|
} else if (!strcmp(*argv, "-server_name")) {
|
||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
server_name = *(++argv);
|
server_name = *(++argv);
|
||||||
|
} else if (!strcmp(*argv, "-trusted_ca_keys")) {
|
||||||
|
trusted_ca_keys = 1;
|
||||||
} else if (!strcmp(*argv, "-renegotiation_info")) {
|
} else if (!strcmp(*argv, "-renegotiation_info")) {
|
||||||
renegotiation_info = 1;
|
renegotiation_info = 1;
|
||||||
} else if (!strcmp(*argv, "-renegotiation_info_scsv")) {
|
} else if (!strcmp(*argv, "-renegotiation_info_scsv")) {
|
||||||
@@ -202,6 +206,13 @@ bad:
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trusted_ca_keys) {
|
||||||
|
if (tls_ctx_enable_trusted_ca_keys(&ctx, 1) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cacertfile) {
|
if (cacertfile) {
|
||||||
if (tls_ctx_set_ca_certificates(&ctx, cacertfile, verify_depth) != 1) {
|
if (tls_ctx_set_ca_certificates(&ctx, cacertfile, verify_depth) != 1) {
|
||||||
fprintf(stderr, "%s: failed to load CA certificate\n", prog);
|
fprintf(stderr, "%s: failed to load CA certificate\n", prog);
|
||||||
|
|||||||
Reference in New Issue
Block a user