Update X509 and certgen tool

This commit is contained in:
Zhi Guan
2023-01-28 22:00:22 +08:00
parent c4c11ffe6b
commit ec7700c17c
16 changed files with 761 additions and 196 deletions

View File

@@ -1176,7 +1176,7 @@ const ASN1_OID_INFO *asn1_oid_info_from_oid(const ASN1_OID_INFO *infos, size_t i
{
size_t i;
if (!infos || !infos_cnt || oid <= 0) {
if (!infos || !infos_cnt || oid < 0) {
error_print();
return NULL;
}

View File

@@ -114,7 +114,7 @@ int http_get(const char *uri, uint8_t *buf, size_t *contentlen, size_t buflen)
tls_socket_t sock;
char get[sizeof(HTTP_GET_TEMPLATE) + sizeof(host) + sizeof(path)];
int getlen;
char response[512];
char response[1024];
uint8_t *p;
size_t len;
size_t left;
@@ -150,13 +150,17 @@ int http_get(const char *uri, uint8_t *buf, size_t *contentlen, size_t buflen)
error_print();
goto end;
}
if ((len = recv(sock, response, sizeof(response), 0)) <= 0) {
if ((len = recv(sock, response, sizeof(response) - 1, 0)) <= 0) {
error_print();
goto end;
}
// process response header and retrieve left
if (http_parse_response(response, len, &p, contentlen, &left) != 1) {
response[len] = 0;
fprintf(stderr, "Response:\n%s\n", response);
error_print();
goto end;
}

View File

@@ -1188,7 +1188,7 @@ int x509_cert_sign(
return 1;
}
int x509_cert_verify(const uint8_t *a, size_t alen,
int x509_signed_verify(const uint8_t *a, size_t alen,
const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len)
{
int ret;
@@ -1199,7 +1199,7 @@ int x509_cert_verify(const uint8_t *a, size_t alen,
size_t siglen;
SM2_SIGN_CTX verify_ctx;
if (x509_certificate_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1
if (x509_signed_from_der(&tbs, &tbslen, &sig_alg, &sig, &siglen, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
@@ -1218,8 +1218,7 @@ int x509_cert_verify(const uint8_t *a, size_t alen,
return ret;
}
// TODO: return an extra error code
int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen,
int x509_signed_verify_by_ca_cert(const uint8_t *a, size_t alen,
const uint8_t *cacert, size_t cacertlen,
const char *signer_id, size_t signer_id_len)
{
@@ -1227,7 +1226,7 @@ int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen,
SM2_KEY public_key;
if (x509_cert_get_subject_public_key(cacert, cacertlen, &public_key) != 1
|| (ret = x509_cert_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) {
|| (ret = x509_signed_verify(a, alen, &public_key, signer_id, signer_id_len)) < 0) {
error_print();
return -1;
}
@@ -1235,6 +1234,17 @@ int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen,
return ret;
}
int x509_cert_verify_by_ca_cert(const uint8_t *a, size_t alen,
const uint8_t *cacert, size_t cacertlen,
const char *signer_id, size_t signer_id_len)
{
if (x509_signed_verify_by_ca_cert(a, alen, cacert, cacertlen, signer_id, signer_id_len) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_cert_to_der(const uint8_t *a, size_t alen, uint8_t **out, size_t *outlen)
{
return asn1_any_to_der(a, alen, out, outlen);

View File

@@ -775,13 +775,14 @@ int x509_issuing_distribution_point_from_der(
int ret;
const uint8_t *d;
size_t dlen;
const uint8_t *a;
size_t alen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
/*
if (x509_explicit_distribution_point_name_from_der(0, dist_point_choice, dist_point, dist_point_len, &d, &dlen) < 0
if (asn1_explicit_from_der(0, &a, &alen, &d, &dlen) < 0
|| asn1_implicit_boolean_from_der(1, only_contains_user_certs, &d, &dlen) < 0
|| asn1_implicit_boolean_from_der(2, only_contains_ca_certs, &d, &dlen) < 0
|| asn1_implicit_bits_from_der(3, only_some_reasons, &d, &dlen) < 0
@@ -791,7 +792,11 @@ int x509_issuing_distribution_point_from_der(
error_print();
return -1;
}
*/
if (x509_distribution_point_name_from_der(dist_point_choice, dist_point, dist_point_len, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
}
return 1;
}
@@ -812,8 +817,8 @@ int x509_issuing_distribution_point_print(FILE *fp, int fmt, int ind, const char
if ((ret = asn1_implicit_boolean_from_der(2, &val, &d, &dlen)) < 0) goto end;
if (!ret) val = 0;
format_print(fp, fmt, ind, "onlyContainsCACerts: %s\n", asn1_boolean_name(val));
if ((ret = x509_implicit_crl_reason_from_der(3, &val, &d, &dlen)) < 0) goto end;
if (ret) format_print(fp, fmt, ind, "onlySomeReasons: %s\n", x509_crl_reason_name(val));
if ((ret = asn1_implicit_bits_from_der(3, &val, &d, &dlen)) < 0) goto end;
if (ret) x509_revoke_reasons_print(fp, fmt, ind, "onlySomeReasons", val);
if ((ret = asn1_implicit_boolean_from_der(4, &val, &d, &dlen)) < 0) goto end;
if (!ret) val = 0;
format_print(fp, fmt, ind, "indirectCRL: %s\n", asn1_boolean_name(val));
@@ -984,6 +989,16 @@ int x509_crl_exts_add_authority_key_identifier(
return 1;
}
int x509_crl_exts_add_default_authority_key_identifier(uint8_t *exts, size_t *extslen, size_t maxlen,
const SM2_KEY *public_key)
{
if (x509_exts_add_default_authority_key_identifier(exts, extslen, maxlen, public_key) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_crl_exts_add_issuer_alt_name(
uint8_t *exts, size_t *extslen, size_t maxlen,
int critical,
@@ -1005,11 +1020,15 @@ int x509_crl_exts_add_crl_number_ex(
uint8_t *p = val;
size_t vlen = 0;
if (num < 0) {
return 0;
}
exts += *extslen;
if (asn1_int_to_der(num, &p, &vlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|| x509_crl_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|| asn1_length_le(curlen, maxlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
|| x509_crl_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
error_print();
return -1;
}
@@ -1021,9 +1040,11 @@ int x509_crl_exts_add_crl_number(
int critical, int num)
{
int oid = OID_ce_crl_number;
if (x509_crl_exts_add_crl_number_ex(exts, extslen, maxlen, oid, critical, num) != 1) {
error_print();
return -1;
int ret;
if ((ret = x509_crl_exts_add_crl_number_ex(exts, extslen, maxlen, oid, critical, num)) != 1) {
if (ret < 0) error_print();
return ret;
}
return 1;
}
@@ -1034,9 +1055,11 @@ int x509_crl_exts_add_delta_crl_indicator(
int num)
{
int oid = OID_ce_delta_crl_indicator;
if (x509_crl_exts_add_crl_number_ex(exts, extslen, maxlen, oid, critical, num) != 1) {
error_print();
return -1;
int ret;
if ((ret = x509_crl_exts_add_crl_number_ex(exts, extslen, maxlen, oid, critical, num)) != 1) {
if (ret < 0) error_print();
return ret;
}
return 1;
}
@@ -1054,25 +1077,32 @@ int x509_crl_exts_add_issuing_distribution_point(
int oid = OID_ce_issuing_distribution_point;
size_t curlen = *extslen;
uint8_t val[512];
uint8_t *p = val;
size_t vlen = 0;
uint8_t *p = val;
size_t len = 0;
exts += *extslen;
if (x509_issuing_distribution_point_to_der(
dist_point_uri, dist_point_uri_len,
only_contains_user_certs,
only_contains_ca_certs,
only_some_reasons,
indirect_crl,
only_contains_attr_certs, NULL, &curlen) != 1
|| asn1_length_le(curlen, maxlen) != 1
only_contains_attr_certs, NULL, &len) != 1
|| asn1_length_le(len, sizeof(val)) != 1
|| x509_issuing_distribution_point_to_der(
dist_point_uri, dist_point_uri_len,
only_contains_user_certs,
only_contains_ca_certs,
only_some_reasons,
indirect_crl,
only_contains_attr_certs, &exts, extslen) != 1) {
only_contains_attr_certs, &p, &vlen) != 1) {
error_print();
return -1;
}
exts += *extslen;
if (x509_crl_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
|| asn1_length_le(curlen, maxlen) != 1
|| x509_crl_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
error_print();
return -1;
}
@@ -1470,21 +1500,24 @@ int x509_crl_from_der_ex(
return 1;
}
int x509_crl_verify(const uint8_t *a, size_t alen,
const SM2_KEY *pub_key, const char *signer_id, size_t signer_id_len)
{
// change x509_cert_verify to x509_verify
if (x509_cert_verify(a, alen, pub_key, signer_id, signer_id_len) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_crl_verify_by_ca_cert(const uint8_t *a, size_t alen,
const uint8_t *cert, size_t certlen, const char *signer_id, size_t signer_id_len)
{
if (x509_cert_verify_by_ca_cert(a, alen, cert, certlen, signer_id, signer_id_len) != 1) {
const uint8_t *crl_issuer;
size_t crl_issuer_len;
const uint8_t *ca_subject;
size_t ca_subject_len;
if (x509_crl_get_issuer(a, alen, &crl_issuer, &crl_issuer_len) != 1
|| x509_cert_get_subject(cert, certlen, &ca_subject, &ca_subject_len) != 1) {
error_print();
return -1;
}
if (x509_name_equ(crl_issuer, crl_issuer_len, ca_subject, ca_subject_len) != 1) {
error_print();
return -1;
}
if (x509_signed_verify_by_ca_cert(a, alen, cert, certlen, signer_id, signer_id_len) != 1) {
error_print();
return -1;
}
@@ -1542,7 +1575,7 @@ int x509_crl_get_details(const uint8_t *a, size_t alen,
return 1;
}
int x509_crl_validate(const uint8_t *a, size_t alen, time_t now, const uint8_t *ca_subject, size_t ca_subject_len)
int x509_crl_validate(const uint8_t *a, size_t alen, time_t now)
{
int version;
int inner_sig_alg;
@@ -1568,10 +1601,6 @@ int x509_crl_validate(const uint8_t *a, size_t alen, time_t now, const uint8_t *
error_print();
return -1;
}
if (issuer_len != ca_subject_len || memcmp(issuer, ca_subject, ca_subject_len) != 0) {
error_print();
return -1;
}
// this_update <= now < next_update
if (now < this_update) {
error_print();

View File

@@ -25,24 +25,41 @@
int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen,
int oid, int critical, const uint8_t *d, size_t dlen)
int x509_ext_to_der_ex(int oid, int critical, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
{
uint8_t *val = NULL;
uint8_t *p = val;
size_t curlen = *extslen;
size_t vlen = 0;
size_t len = 0;
if (!(val = malloc(32 + dlen))) {
if (asn1_sequence_to_der(d, dlen, NULL, &vlen) != 1) {
error_print();
return -1;
}
if (x509_ext_id_to_der(oid, NULL, &len) != 1
|| asn1_boolean_to_der(critical, NULL, &len) < 0
|| asn1_tag_to_der(ASN1_TAG_OCTET_STRING, NULL, &len) != 1
|| asn1_length_to_der(vlen, NULL, &len) != 1
|| asn1_sequence_to_der(d, dlen, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| x509_ext_id_to_der(oid, out, outlen) != 1
|| asn1_boolean_to_der(critical, out, outlen) < 0
|| asn1_tag_to_der(ASN1_TAG_OCTET_STRING, out, outlen) != 1
|| asn1_length_to_der(vlen, out, outlen) != 1
|| asn1_sequence_to_der(d, dlen, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen,
int oid, int critical, const uint8_t *d, size_t dlen)
{
size_t curlen = *extslen;
exts += *extslen;
if (asn1_sequence_to_der(d, dlen, &p, &vlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, NULL, &curlen) != 1
if (x509_ext_to_der_ex(oid, critical, d, dlen, NULL, &curlen) != 1
|| asn1_length_le(curlen, maxlen) != 1
|| x509_ext_to_der(oid, critical, val, vlen, &exts, extslen) != 1) {
|| x509_ext_to_der_ex(oid, critical, d, dlen, &exts, extslen) != 1) {
error_print();
return -1;
}
@@ -127,6 +144,22 @@ int x509_exts_add_subject_key_identifier(uint8_t *exts, size_t *extslen, size_t
return 1;
}
int x509_exts_add_subject_key_identifier_ex(uint8_t *exts, size_t *extslen, size_t maxlen,
int critical, const SM2_KEY *subject_key)
{
uint8_t buf[65];
uint8_t id[32];
sm2_point_to_uncompressed_octets(&subject_key->public_key, buf);
sm3_digest(buf, sizeof(buf), id);
if (x509_exts_add_subject_key_identifier(exts, extslen, maxlen, critical, id, 32) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_exts_add_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int bits)
{
int oid = OID_ce_key_usage;
@@ -1944,14 +1977,15 @@ int x509_distribution_points_to_der(const char *http_uri, size_t http_urilen,
int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
{
int ret;
int tag;
if ((ret = asn1_implicit_from_der(*choice, d, dlen, in, inlen)) != 1) {
if ((ret = asn1_any_type_from_der(&tag, d, dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return -1;
}
switch (*choice) {
case 0:
case 1:
switch (tag) {
case ASN1_TAG_EXPLICIT(0):
case ASN1_TAG_EXPLICIT(1):
break;
default:
error_print();