mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 17:06:25 +08:00
Update CRL functions and tools
This commit is contained in:
30
src/file.c
30
src/file.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2023 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.
|
||||
@@ -33,3 +33,31 @@ int file_size(FILE *fp, size_t *size)
|
||||
*size = st.st_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int file_read_all(const char *file, uint8_t **out, size_t *outlen)
|
||||
{
|
||||
int ret = -1;
|
||||
FILE *fp = NULL;
|
||||
size_t fsize;
|
||||
uint8_t *buf = NULL;
|
||||
|
||||
if (!(fp = fopen(file, "r"))
|
||||
|| file_size(fp, &fsize) != 1
|
||||
|| (buf = malloc(fsize)) == NULL) {
|
||||
error_print();
|
||||
goto end;
|
||||
}
|
||||
if (fread(buf, 1, fsize, fp) != fsize) {
|
||||
error_print();
|
||||
goto end;
|
||||
}
|
||||
*out = buf;
|
||||
*outlen = fsize;
|
||||
buf = NULL;
|
||||
ret = 1;
|
||||
end:
|
||||
if (fp) fclose(fp);
|
||||
if (buf) free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
70
src/http.c
70
src/http.c
@@ -1,5 +1,4 @@
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
@@ -65,7 +64,7 @@ static int socket_recv_all(int sock, uint8_t *buf, size_t len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int http_parse_response(uint8_t *buf, size_t buflen, uint8_t **content, size_t *contentlen, size_t *left)
|
||||
int http_parse_response(char *buf, size_t buflen, uint8_t **content, size_t *contentlen, size_t *left)
|
||||
{
|
||||
char *ok = "HTTP/1.1 200 OK\r\n";
|
||||
char *p;
|
||||
@@ -75,14 +74,14 @@ int http_parse_response(uint8_t *buf, size_t buflen, uint8_t **content, size_t *
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!(p = strnstr((char *)buf, "\r\n\r\n", buflen))) {
|
||||
if (!(p = strnstr(buf, "\r\n\r\n", buflen))) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*content = (uint8_t *)(p + 4);
|
||||
headerlen = *content - buf;
|
||||
headerlen = *content - (uint8_t *)buf;
|
||||
|
||||
if (!(p = strnstr((char *)buf, "\r\nContent-Length: ", headerlen))) {
|
||||
if (!(p = strnstr(buf, "\r\nContent-Length: ", headerlen))) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -104,10 +103,9 @@ int http_parse_response(uint8_t *buf, size_t buflen, uint8_t **content, size_t *
|
||||
|
||||
#define HTTP_GET_TEMPLATE "GET %s HTTP/1.1\r\n" "Host: %s\r\n" "\r\n\r\n"
|
||||
|
||||
int http_get(const char *uri, uint8_t *buf, size_t buflen,
|
||||
uint8_t **content, size_t *contentlen)
|
||||
int http_get(const char *uri, uint8_t *buf, size_t *contentlen, size_t buflen)
|
||||
{
|
||||
char *uribuf = NULL;
|
||||
int ret = -1;
|
||||
char host[128];
|
||||
int port;
|
||||
char path[256];
|
||||
@@ -116,16 +114,22 @@ int http_get(const char *uri, uint8_t *buf, size_t buflen,
|
||||
tls_socket_t sock;
|
||||
char get[sizeof(HTTP_GET_TEMPLATE) + sizeof(host) + sizeof(path)];
|
||||
int getlen;
|
||||
char response[512];
|
||||
uint8_t *p;
|
||||
size_t len;
|
||||
size_t left;
|
||||
|
||||
// parse uri
|
||||
// parse uri and compose request
|
||||
if (http_parse_uri(uri, host, &port, path) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((getlen = snprintf(get, sizeof(get), HTTP_GET_TEMPLATE, path, host)) <= 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// connect
|
||||
// connect and send request
|
||||
if (!(hp = gethostbyname(host))) {
|
||||
error_print();
|
||||
return -1;
|
||||
@@ -140,42 +144,36 @@ int http_get(const char *uri, uint8_t *buf, size_t buflen,
|
||||
}
|
||||
if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// request
|
||||
if ((getlen = snprintf(get, sizeof(get),
|
||||
"GET %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"\r\n\r\n", path, host)) <= 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
goto end;
|
||||
}
|
||||
if (send(sock, get, strlen(get), 0) != getlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
goto end;
|
||||
}
|
||||
if ((len = recv(sock, response, sizeof(response), 0)) <= 0) {
|
||||
error_print();
|
||||
goto end;
|
||||
}
|
||||
|
||||
// response
|
||||
if ((len = recv(sock, buf, buflen, 0)) <= 0) {
|
||||
// process response header and retrieve left
|
||||
if (http_parse_response(response, len, &p, contentlen, &left) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
goto end;
|
||||
}
|
||||
if (http_parse_response(buf, len, content, contentlen, &left) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
if (!buf || buflen < *contentlen) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
memcpy(buf, p, *contentlen - left);
|
||||
if (left) {
|
||||
if (len + left > buflen) {
|
||||
error_print(); // buf is not enough
|
||||
return -1;
|
||||
}
|
||||
if (socket_recv_all(sock, buf + len, left) != 1) {
|
||||
if (socket_recv_all(sock, buf + *contentlen - left, left) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
return 1;
|
||||
end:
|
||||
close(sock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2023 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.
|
||||
@@ -382,6 +382,23 @@ int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_sign_finish_fixlen(SM2_SIGN_CTX *ctx, size_t siglen, uint8_t *sig)
|
||||
{
|
||||
int ret;
|
||||
uint8_t dgst[SM3_DIGEST_SIZE];
|
||||
|
||||
if (!ctx || !sig || !siglen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
sm3_finish(&ctx->sm3_ctx, dgst);
|
||||
if ((ret = sm2_sign_fixlen(&ctx->key, dgst, siglen, sig)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sm2_verify_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen)
|
||||
{
|
||||
if (!ctx || !key) {
|
||||
|
||||
@@ -729,7 +729,7 @@ int x509_ext_from_der(int *oid, uint32_t *nodes, size_t *nodes_cnt,
|
||||
if (ret < 0) error_print();
|
||||
return ret;
|
||||
}
|
||||
*critical = 0;
|
||||
*critical = 0; // FIXME: do not set default
|
||||
if (x509_ext_id_from_der(oid, nodes, nodes_cnt, &d, &dlen) != 1
|
||||
|| asn1_boolean_from_der(critical, &d, &dlen) < 0
|
||||
|| asn1_octet_string_from_der(val, vlen, &d, &dlen) != 1
|
||||
@@ -1041,6 +1041,48 @@ int x509_certificate_to_der(
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_signed_to_der(
|
||||
const uint8_t *tbs, size_t tbslen, // full TLV
|
||||
int signature_algor,
|
||||
const uint8_t *sig, size_t siglen,
|
||||
uint8_t **out, size_t *outlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
if (asn1_data_to_der(tbs, tbslen, NULL, &len) != 1
|
||||
|| x509_signature_algor_to_der(signature_algor, NULL, &len) != 1
|
||||
|| asn1_bit_octets_to_der(sig, siglen, NULL, &len) != 1
|
||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||
|| asn1_data_to_der(tbs, tbslen, out, outlen) != 1
|
||||
|| x509_signature_algor_to_der(signature_algor, out, outlen) != 1
|
||||
|| asn1_bit_octets_to_der(sig, siglen, out, outlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_signed_from_der(const uint8_t **tbs, size_t *tbs_len,
|
||||
int *sig_alg, const uint8_t **sig, size_t *siglen,
|
||||
const uint8_t **in, size_t *inlen)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *d;
|
||||
size_t dlen;
|
||||
|
||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||
if (ret < 0) error_print();
|
||||
return -1;
|
||||
}
|
||||
if (asn1_any_from_der(tbs, tbs_len, &d, &dlen) != 1
|
||||
|| x509_signature_algor_from_der(sig_alg, &d, &dlen) != 1
|
||||
|| asn1_bit_octets_from_der(sig, siglen, &d, &dlen) != 1
|
||||
|| asn1_length_is_zero(dlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_certificate_from_der(
|
||||
const uint8_t **tbs, size_t *tbslen, // full TLV
|
||||
int *signature_algor,
|
||||
@@ -1571,6 +1613,8 @@ int x509_certs_get_cert_by_issuer_and_serial_number(
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 这里面需要validate的类型是两种,一种直接得到了实际值,因此可以直接对实际值做验证
|
||||
// 另一种是SEQUENCE OF类型,本质上是完整的a,alen,因此这种类型实际上可以用from_der来解析
|
||||
int x509_cert_validate(const uint8_t *cert, size_t certlen, int cert_type,
|
||||
int *path_len_constraints)
|
||||
{
|
||||
|
||||
1193
src/x509_crl.c
1193
src/x509_crl.c
File diff suppressed because it is too large
Load Diff
168
src/x509_ext.c
168
src/x509_ext.c
@@ -284,23 +284,15 @@ int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen,
|
||||
int critical, const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen)
|
||||
int x509_exts_add_crl_distribution_points_ex(uint8_t *exts, size_t *extslen, size_t maxlen,
|
||||
int oid, int critical, const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen)
|
||||
{
|
||||
int oid = OID_ce_crl_distribution_points;
|
||||
size_t curlen = *extslen;
|
||||
uint8_t val[256];
|
||||
uint8_t *p = val;
|
||||
size_t vlen = 0;
|
||||
size_t len = 0;
|
||||
|
||||
// The extension SHOULD be non-critical, but this profile
|
||||
// RECOMMENDS support for this extension by CAs and applications.
|
||||
if (critical) {
|
||||
error_print();
|
||||
//return -1;
|
||||
}
|
||||
|
||||
if (x509_distribution_points_to_der(http_uri, http_urilen, ldap_uri, ldap_urilen, NULL, &len) != 1
|
||||
|| asn1_length_le(len, sizeof(val)) != 1
|
||||
|| x509_distribution_points_to_der(http_uri, http_urilen, ldap_uri, ldap_urilen, &p, &vlen) != 1) {
|
||||
@@ -317,6 +309,18 @@ int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen,
|
||||
int critical, const char *http_uri, size_t http_urilen, const char *ldap_uri, size_t ldap_urilen)
|
||||
{
|
||||
int oid = OID_ce_crl_distribution_points;
|
||||
if (x509_exts_add_crl_distribution_points_ex(exts, extslen, maxlen,
|
||||
oid, critical, http_uri, http_urilen, ldap_uri, ldap_urilen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen,
|
||||
int critical, int skip_certs)
|
||||
{
|
||||
@@ -705,6 +709,38 @@ int x509_authority_key_identifier_from_der(
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_authority_key_identifier_validate(const uint8_t *a, size_t alen)
|
||||
{
|
||||
const uint8_t *keyid;
|
||||
size_t keyid_len;
|
||||
const uint8_t *issuer;
|
||||
size_t issuer_len;
|
||||
const uint8_t *serial;
|
||||
size_t serial_len;
|
||||
|
||||
if (x509_authority_key_identifier_from_der(
|
||||
&keyid, &keyid_len,
|
||||
&issuer, &issuer_len,
|
||||
&serial, &serial_len, &a, &alen) != 1
|
||||
|| asn1_length_is_zero(alen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!keyid && !issuer && !serial) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (issuer) {
|
||||
/*
|
||||
if (asn1_general_names_validate(issuer, issuer_len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_authority_key_identifier_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
int ret;
|
||||
@@ -1118,6 +1154,12 @@ int x509_certificate_policies_add_policy_information(uint8_t *d, size_t *dlen, s
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_certificate_polices_validate(const uint8_t *d, size_t dlen)
|
||||
{
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_certificate_policies_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
@@ -1201,6 +1243,16 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_policy_mapping_validate(const uint8_t *a, size_t alen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_policy_mappings_validate(const uint8_t *d, size_t dlen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_policy_mappings_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
@@ -1343,6 +1395,8 @@ int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t *
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// 这个函数原型可能要改一下
|
||||
int x509_basic_constraints_validate(int ca, int path_len_cons, int cert_type)
|
||||
{
|
||||
/*
|
||||
@@ -1598,6 +1652,12 @@ int x509_policy_constraints_from_der(
|
||||
return 1;
|
||||
}
|
||||
|
||||
int x509_policy_constraints_validate(const uint8_t *a, size_t alen)
|
||||
{
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int x509_policy_constraints_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
int ret, val;
|
||||
@@ -1670,6 +1730,7 @@ int x509_ext_key_usage_from_der(int *oids, size_t *oids_cnt, size_t max_cnt, con
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 这个函数原型可能也要改一下
|
||||
int x509_ext_key_usage_validate(const int *oids, size_t oids_cnt, int cert_type)
|
||||
{
|
||||
int ret = -1;
|
||||
@@ -1994,6 +2055,11 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_distribution_points_validate(const uint8_t *d, size_t dlen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||
{
|
||||
const uint8_t *p;
|
||||
@@ -2055,6 +2121,69 @@ int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
|
||||
}
|
||||
|
||||
switch (oid) {
|
||||
case OID_ce_authority_key_identifier:
|
||||
if (critical == X509_critical) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
if (x509_authority_key_identifier(val, vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
break;
|
||||
case OID_ce_subject_key_identifier:
|
||||
if (critical == X509_critical) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
if (asn1_octet_string_from_der(&p, &len, &val, &vlen) != 1
|
||||
|| asn1_length_is_zero(vlen) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!p || !len) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_ce_key_usage:
|
||||
if (critical != X509_critical) {
|
||||
error_print();
|
||||
// conforming CAs SHOULD mark this extension as critical.
|
||||
}
|
||||
if (asn1_bits_from_der(&key_usage, &val, &vlen) != 1
|
||||
|| x509_key_usage_validate(key_usage, cert_type) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_ce_certificate_policies:
|
||||
break;
|
||||
case OID_ce_policy_mappings:
|
||||
if (critical != X509_critical) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_ce_subject_alt_name:
|
||||
break;
|
||||
case OID_ce_issuer_alt_name:
|
||||
if (critical == X509_critical) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case OID_ce_subject_directory_attributes:
|
||||
if (critical == X509_critical) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case OID_ce_basic_constraints:
|
||||
if (x509_basic_constraints_from_der(&ca, &path_len, &val, &vlen) != 1
|
||||
|| x509_basic_constraints_validate(ca, path_len, cert_type) != 1) {
|
||||
@@ -2063,13 +2192,7 @@ int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
|
||||
}
|
||||
break;
|
||||
|
||||
case OID_ce_key_usage:
|
||||
if (asn1_bits_from_der(&key_usage, &val, &vlen) != 1
|
||||
|| x509_key_usage_validate(key_usage, cert_type) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case OID_ce_ext_key_usage:
|
||||
if (x509_ext_key_usage_from_der(ext_key_usages, &ext_key_usages_cnt,
|
||||
@@ -2080,20 +2203,15 @@ int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
|
||||
}
|
||||
break;
|
||||
|
||||
case OID_ce_authority_key_identifier:
|
||||
case OID_ce_subject_key_identifier:
|
||||
case OID_ce_certificate_policies:
|
||||
case OID_ce_policy_mappings:
|
||||
case OID_ce_subject_alt_name:
|
||||
case OID_ce_issuer_alt_name:
|
||||
case OID_ce_subject_directory_attributes:
|
||||
case OID_ce_name_constraints:
|
||||
case OID_ce_policy_constraints:
|
||||
case OID_ce_crl_distribution_points:
|
||||
case OID_ce_inhibit_any_policy:
|
||||
case OID_ce_freshest_crl:
|
||||
|
||||
break;
|
||||
default:
|
||||
if (critical) {
|
||||
if (critical == X509_critical) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user