mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-21 20:53:48 +08:00
Update TLCP
This commit is contained in:
1043
src/tlcp.c
1043
src/tlcp.c
File diff suppressed because it is too large
Load Diff
@@ -222,7 +222,7 @@ const char *tls_alert_level_name(int level)
|
||||
case TLS_alert_level_warning: return "warning";
|
||||
case TLS_alert_level_fatal: return "fatal";
|
||||
}
|
||||
error_print_msg("unknown alert level %d", level);
|
||||
error_print_msg("unknown alert level %d\n", level);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -253,6 +253,7 @@ const char *tls_alert_description_text(int description)
|
||||
case TLS_alert_internal_error: return "internal_error";
|
||||
case TLS_alert_user_canceled: return "user_canceled";
|
||||
case TLS_alert_no_renegotiation: return "no_renegotiation";
|
||||
case TLS_alert_unsupported_extension: return "unsupported_extension";
|
||||
case TLS_alert_unsupported_site2site: return "unsupported_site2site";
|
||||
case TLS_alert_no_area: return "no_area";
|
||||
case TLS_alert_unsupported_areatype: return "unsupported_areatype";
|
||||
@@ -468,6 +469,17 @@ int tls_extensions_print(FILE *fp, const uint8_t *exts, size_t extslen, int form
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_hello_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent)
|
||||
{
|
||||
format_print(fp, format, indent, "HelloRequest\n");
|
||||
indent += 4;
|
||||
if (data || datalen > 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_client_hello_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent)
|
||||
{
|
||||
int ret = -1;
|
||||
@@ -580,22 +592,6 @@ int tls_certificate_print(FILE *fp, const uint8_t *data, size_t datalen, int for
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tlcp_server_key_exchange_pke_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent)
|
||||
{
|
||||
const uint8_t *sig = data;
|
||||
size_t siglen = datalen;
|
||||
/*
|
||||
if (tls_uint16array_from_bytes(&sig, &siglen, &data, &datalen) != 1
|
||||
|| datalen > 0) {
|
||||
error_print();
|
||||
}
|
||||
*/
|
||||
format_print(fp, format, indent, "ServerKeyExchange\n");
|
||||
indent += 4;
|
||||
format_bytes(fp, format, indent, "signature", sig, siglen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen,
|
||||
int format, int indent)
|
||||
{
|
||||
@@ -675,6 +671,32 @@ int tls_server_key_exchange_print(FILE *fp, const uint8_t *data, size_t datalen,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_certificate_subjects_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *a;
|
||||
size_t alen;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
while (dlen) {
|
||||
const uint8_t *name;
|
||||
size_t namelen;
|
||||
|
||||
if (tls_uint16array_from_bytes(&a, &alen, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_sequence_from_der(&name, &namelen, &a, &alen) != 1
|
||||
|| asn1_length_is_zero(alen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
x509_name_print(fp, fmt, ind, "DistinguishedName", name, namelen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen, int format, int indent)
|
||||
{
|
||||
const uint8_t *cert_types;
|
||||
@@ -688,7 +710,8 @@ int tls_certificate_request_print(FILE *fp, const uint8_t *data, size_t datalen,
|
||||
format_print(fp, format, indent + 4, "%s\n", tls_cert_type_name(*cert_types++));
|
||||
}
|
||||
if (tls_uint16array_from_bytes(&ca_names, &ca_names_len, &data, &datalen) != 1) goto bad;
|
||||
format_bytes(fp, format, indent, "CAnames", ca_names, ca_names_len);
|
||||
tls_certificate_subjects_print(fp, format, indent, "CAnames", ca_names, ca_names_len);
|
||||
|
||||
return 1;
|
||||
bad:
|
||||
error_print();
|
||||
@@ -806,6 +829,9 @@ int tls_handshake_print(FILE *fp, const uint8_t *handshake, size_t handshakelen,
|
||||
return -1;
|
||||
}
|
||||
switch (type) {
|
||||
case TLS_handshake_hello_request:
|
||||
if (tls_hello_request_print(fp, data, datalen, format, indent) != 1)
|
||||
{ error_print(); return -1; } break;
|
||||
case TLS_handshake_client_hello:
|
||||
if (tls_client_hello_print(fp, data, datalen, format, indent) != 1)
|
||||
{ error_print(); return -1; } break;
|
||||
@@ -871,6 +897,8 @@ int tls_application_data_print(FILE *fp, const uint8_t *data, size_t datalen, in
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 当消息为ClientKeyExchange,ServerKeyExchange,需要密码套件中的密钥交换算法信息
|
||||
// 当消息为加密的Finished,记录类型为Handshake,但是记录负载数据中没有Handshake头
|
||||
int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int format, int indent)
|
||||
{
|
||||
const uint8_t *data;
|
||||
@@ -890,6 +918,13 @@ int tls_record_print(FILE *fp, const uint8_t *record, size_t recordlen, int for
|
||||
data = record + 5;
|
||||
datalen = recordlen - 5;
|
||||
|
||||
// 最高字节设置后强制打印记录原始数据
|
||||
if (format >> 24) {
|
||||
format_bytes(fp, format, indent, "Data", data, datalen);
|
||||
fprintf(fp, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (record[0]) {
|
||||
case TLS_record_handshake:
|
||||
if (tls_handshake_print(fp, data, datalen, format, indent) != 1) {
|
||||
|
||||
167
src/x509_cer.c
167
src/x509_cer.c
@@ -547,6 +547,24 @@ int x509_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
|
||||
format_print(fp, fmt, ind, "%s\n", label);
|
||||
ind += 4;
|
||||
|
||||
while (dlen) {
|
||||
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
x509_name_print(fp, fmt, ind, "Name", p, len);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_name_get_value_by_type(const uint8_t *d, size_t dlen, int oid, int *tag, const uint8_t **val, size_t *vlen)
|
||||
{
|
||||
const uint8_t *rdn_d;
|
||||
@@ -587,6 +605,15 @@ int x509_name_get_common_name(const uint8_t *d, size_t dlen, int *tag, const uin
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_name_equ(const uint8_t *a, size_t alen, const uint8_t *b, size_t blen)
|
||||
{
|
||||
if (alen != blen || memcmp(a, b, blen) != 0) {
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
@@ -1407,6 +1434,21 @@ int x509_certs_get_cert_by_index(const uint8_t *d, size_t dlen, int index, const
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_certs_get_last(const uint8_t *d, size_t dlen, const uint8_t **cert, size_t *certlen)
|
||||
{
|
||||
if (!dlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
while (dlen) {
|
||||
if (x509_cert_from_der(cert, certlen, &d, &dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen,
|
||||
const uint8_t *subject, size_t subject_len, const uint8_t **cert, size_t *certlen)
|
||||
{
|
||||
@@ -1420,7 +1462,11 @@ int x509_certs_get_cert_by_subject(const uint8_t *d, size_t dlen,
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (subj_len == subject_len && memcmp(subj, subject, subj_len) == 0) {
|
||||
if (x509_cert_get_subject(a, alen, &subj, &subj_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_name_equ(subj, subj_len, subject, subject_len) == 1) {
|
||||
*cert = a;
|
||||
*certlen = alen;
|
||||
return 1;
|
||||
@@ -1458,6 +1504,125 @@ int x509_certs_get_cert_by_issuer_and_serial_number(
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int x509_certs_verify(const uint8_t *certs, size_t certslen,
|
||||
const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result)
|
||||
{
|
||||
const uint8_t *cert;
|
||||
size_t certlen;
|
||||
const uint8_t *cacert;
|
||||
size_t cacertlen;
|
||||
const uint8_t *name;
|
||||
size_t namelen;
|
||||
|
||||
*verify_result = -1;
|
||||
|
||||
if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
while (certslen) {
|
||||
if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
// 这里应该检查证书是否有效啊, 这个函数应该返回进一步的错误信息
|
||||
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
|
||||
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
cert = cacert;
|
||||
certlen = cacertlen;
|
||||
}
|
||||
if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen,
|
||||
&cacert, &cacertlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
|
||||
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_certs_verify_tlcp(const uint8_t *certs, size_t certslen,
|
||||
const uint8_t *rootcerts, size_t rootcertslen, int depth, int *verify_result)
|
||||
{
|
||||
const uint8_t *signcert;
|
||||
size_t signcertlen;
|
||||
int signcert_verified = 0;
|
||||
const uint8_t *cert;
|
||||
size_t certlen;
|
||||
const uint8_t *cacert;
|
||||
size_t cacertlen;
|
||||
const uint8_t *name;
|
||||
size_t namelen;
|
||||
|
||||
*verify_result = -1;
|
||||
|
||||
if (x509_cert_from_der(&signcert, &signcertlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_cert_from_der(&cert, &certlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
// 要检查这两个证书的类型是否分别为签名和加密证书
|
||||
// FIXME: 检查depth
|
||||
while (certslen) {
|
||||
if (x509_cert_from_der(&cacert, &cacertlen, &certs, &certslen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!signcert_verified) {
|
||||
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
|
||||
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
signcert_verified = 1;
|
||||
}
|
||||
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
|
||||
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
cert = cacert;
|
||||
certlen = cacertlen;
|
||||
}
|
||||
if (x509_cert_get_issuer(cert, certlen, &name, &namelen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (x509_certs_get_cert_by_subject(rootcerts, rootcertslen, name, namelen, &cacert, &cacertlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!signcert_verified) {
|
||||
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
|
||||
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen,
|
||||
SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int x509_certs_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
|
||||
Reference in New Issue
Block a user