Update X.509 Extensions

This commit is contained in:
Zhi Guan
2023-01-31 15:57:53 +08:00
parent ec7700c17c
commit 13eae91d7d
20 changed files with 1348 additions and 497 deletions

View File

@@ -1629,6 +1629,9 @@ int asn1_utc_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *outlen)
error_print();
return -1;
}
if (a == -1) {
return 0;
}
if (asn1_time_to_str(utc_time, a, buf) != 1) {
error_print();
@@ -1704,6 +1707,9 @@ int asn1_generalized_time_to_der_ex(int tag, time_t a, uint8_t **out, size_t *ou
error_print();
return -1;
}
if (a == -1) {
return 0;
}
if (asn1_time_to_str(utc_time, a, buf) != 1) {
error_print();

View File

@@ -721,8 +721,8 @@ int cms_signer_info_print(FILE *fp, int fmt, int ind, const char *label, const u
format_print(fp, fmt, ind, "digestAlgorithm: %s\n", x509_digest_algor_name(val));
if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
if (ret) x509_attributes_print(fp, fmt, ind, "authenticatedAttributes", p, len);
if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "digestEncryptionAlgorithm: %s\n", x509_signature_algor_name(val));
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_signature_algor_print(fp, fmt, ind, "digestEncryptionAlgorithm", p, len);
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
format_bytes(fp, fmt, ind, "encryptedDigest", p, len);
if ((ret = asn1_implicit_set_from_der(1, &p, &len, &d, &dlen)) < 0) goto err;

View File

@@ -59,6 +59,32 @@ int x509_digest_algor_from_name(const char *name)
return info->oid;
}
/*
from RFC 5754 Using SHA2 Algorithms with Cryptographic Message Syntax
2. Message Digest Algorithms
The AlgorithmIdentifier parameters field is OPTIONAL.
Implementations MUST accept SHA2 AlgorithmIdentifiers with absent
parameters. Implementations MUST accept SHA2 AlgorithmIdentifiers
with NULL parameters. Implementations MUST generate SHA2
AlgorithmIdentifiers with absent parameters.
from RFC 5758 Internet X.509 Public Key Infrastructure:
Additional Algorithms and Identifiers for DSA and ECDSA
2. Hash Functions
id-sha224
id-sha256
id-sha384
id-sha512
When one of these OIDs appears in an AlgorithmIdentifier, all
implementations MUST accept both NULL and absent parameters as legal
and equivalent encodings.
*/
int x509_digest_algor_to_der(int oid, uint8_t **out, size_t *outlen)
{
const ASN1_OID_INFO *info;
@@ -234,6 +260,59 @@ static uint32_t oid_rsasign_with_sha384[] = { 1,2,840,113549,1,1,12 };
static uint32_t oid_rsasign_with_sha512[] = { 1,2,840,113549,1,1,13 };
/*
from RFC 3447 Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography
Specifications Version 2.1
Appendix C. ASN.1 module
-- When rsaEncryption is used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.
-- When the following OIDs are used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.
--
md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
from RFC 5754 Using SHA2 Algorithms with Cryptographic Message Syntax
3.3. ECDSA
When any of these four object identifiers appears within an
^ ecdsa-with-SHA224/SHA256/SHA384/SHA512
AlgorithmIdentifier, the parameters field MUST be absent. That is,
the AlgorithmIdentifier SHALL be a SEQUENCE of one component: the OID
ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or ecdsa-
with-SHA512.
from RFC 5758 Internet X.509 Public Key Infrastructure:
Additional Algorithms and Identifiers for DSA and ECDSA
3.1. DSA Signature Algorithm
When the id-dsa-with-sha224 or id-dsa-with-sha256 algorithm
identifier appears in the algorithm field as an AlgorithmIdentifier,
the encoding SHALL omit the parameters field. That is, the
AlgorithmIdentifier SHALL be a SEQUENCE of one component, the OID id-
dsa-with-sha224 or id-dsa-with-sha256.
3.2. ECDSA Signature Algorithm
When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
as an AlgorithmIdentifier, the encoding MUST omit the parameters
field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one
component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
SHA384, or ecdsa-with-SHA512.
*/
static const ASN1_OID_INFO x509_sign_algors[] = {
{ OID_sm2sign_with_sm3, "sm2sign-with-sm3", oid_sm2sign_with_sm3, sizeof(oid_sm2sign_with_sm3)/sizeof(int), X509_ALGOR_ALLOW_EC_NULL_PARAM },
{ OID_rsasign_with_sm3, "rsasign-with-sm3", oid_rsasign_with_sm3, sizeof(oid_rsasign_with_sm3)/sizeof(int), 1 },

View File

@@ -448,7 +448,12 @@ int x509_name_add_rdn(uint8_t *d, size_t *dlen, size_t maxlen,
{
size_t len = 0;
uint8_t *p = d + *dlen;
if (!val && !more) {
if (!val) {
if (more) {
error_print();
return -1;
}
return 0;
}
if (x509_rdn_to_der(oid, tag, val, vlen, NULL, 0, NULL, &len) != 1
@@ -546,7 +551,7 @@ int x509_name_set(uint8_t *d, size_t *dlen, size_t maxlen,
*dlen = 0;
if (x509_name_add_country_name(d, dlen, maxlen, country) < 0
|| x509_name_add_state_or_province_name(d, dlen, maxlen, x509_name_tag(state), (uint8_t *)state, strlen(state)) < 0
|| x509_name_add_state_or_province_name(d, dlen, maxlen, x509_name_tag(state), (uint8_t *)state, _strlen(state)) < 0
|| x509_name_add_locality_name(d, dlen, maxlen, x509_name_tag(locality), (uint8_t *)locality, _strlen(locality)) < 0
|| x509_name_add_organization_name(d, dlen, maxlen, x509_name_tag(org), (uint8_t *)org, _strlen(org)) < 0
|| x509_name_add_organizational_unit_name(d, dlen, maxlen, x509_name_tag(org_unit), (uint8_t *)org_unit, _strlen(org_unit)) < 0
@@ -1118,8 +1123,8 @@ int x509_certificate_print(FILE *fp, int fmt, int ind, const char *label, const
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_tbs_cert_print(fp, fmt, ind, "tbsCertificate", p, len);
if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "signatureAlgorithm: %s\n", x509_signature_algor_name(val));
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_signature_algor_print(fp, fmt, ind, "signatureAlgorithm", p, len);
if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err;
format_bytes(fp, fmt, ind, "signatureValue", p, len);
if (asn1_length_is_zero(dlen) != 1) goto err;

View File

@@ -818,7 +818,7 @@ int x509_issuing_distribution_point_print(FILE *fp, int fmt, int ind, const char
if (!ret) val = 0;
format_print(fp, fmt, ind, "onlyContainsCACerts: %s\n", asn1_boolean_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) x509_revoke_reason_flags_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));
@@ -1299,8 +1299,8 @@ int x509_cert_list_print(FILE *fp, int fmt, int ind, const char *label, const ui
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_tbs_crl_print(fp, fmt, ind, "tbsCertList", p, len);
if (x509_signature_algor_from_der(&val, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "signatureAlgorithm: %s\n", x509_signature_algor_name(val));
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_signature_algor_print(fp, fmt, ind, "signatureAlgorithm", p, len);
if (asn1_bit_octets_from_der(&p, &len, &d, &dlen) != 1) goto err;
format_bytes(fp, fmt, ind, "signatureValue", p, len);
if (asn1_length_is_zero(dlen) != 1) goto err;

View File

@@ -318,7 +318,7 @@ int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen,
}
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, int critical, const char *uri, size_t urilen, const char *ldap_uri, size_t ldap_urilen)
{
size_t curlen = *extslen;
uint8_t val[256];
@@ -326,9 +326,9 @@ int x509_exts_add_crl_distribution_points_ex(uint8_t *exts, size_t *extslen, siz
size_t vlen = 0;
size_t len = 0;
if (x509_distribution_points_to_der(http_uri, http_urilen, ldap_uri, ldap_urilen, NULL, &len) != 1
if (x509_uri_as_distribution_points_to_der(uri, urilen, -1, NULL, 0, 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) {
|| x509_uri_as_distribution_points_to_der(uri, urilen, -1, NULL, 0, &p, &vlen) != 1) {
error_print();
return -1;
}
@@ -679,6 +679,77 @@ int x509_general_names_add_registered_id(uint8_t *gns, size_t *gnslen, size_t ma
return 1;
}
int x509_uri_as_general_names_to_der_ex(int tag, const char *uri, size_t urilen,
uint8_t **out, size_t *outlen)
{
int choice = X509_gn_uniform_resource_identifier;
size_t len = 0;
if (!uri || !urilen) {
return 0;
}
if (x509_general_name_to_der(choice, (uint8_t *)uri, urilen, NULL, &len) != 1
|| asn1_sequence_header_to_der_ex(tag, len, out, outlen) != 1
|| x509_general_name_to_der(choice, (uint8_t *)uri, urilen, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
/*
int x509_uri_as_general_names_from_der_ex(int tag, const uint8_t **uri, size_t *urilen,
const uint8_t **in, size_t *inlen)
{
int choice = X509_gn_uniform_resource_identifier;
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_sequence_from_der_ex(tag, &d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (x509_general_names_get_first(d, dlen, NULL, choice, uri, urilen) < 0) {
error_print();
return -1;
}
return 1;
}
*/
int x509_general_names_get_next(const uint8_t *gns, size_t gns_len, const uint8_t **ptr, int choice, const uint8_t **d, size_t *dlen)
{
if (*ptr > gns + gns_len) {
error_print();
return -1;
}
gns_len -= (*ptr - gns);
while (gns_len) {
int tag;
if (x509_general_name_from_der(&tag, d, dlen, ptr, &gns_len) != 1) {
error_print();
return -1;
}
if (tag == choice) {
return 1;
}
}
return 0;
}
int x509_general_names_get_first(const uint8_t *gns, size_t gns_len, const uint8_t **ptr, int choice, const uint8_t **d, size_t *dlen)
{
int ret;
*ptr = gns;
if ((ret = x509_general_names_get_next(gns, gns_len, ptr, choice, d, dlen)) < 0) {
error_print();
return - 1;
}
return ret;
}
int x509_general_names_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
int choice;
@@ -1843,7 +1914,7 @@ CRL Distribution Points
必须包含 DN, certificateRevocationList 应包含host部分
*/
static const char *x509_revoke_reasons[] = {
static const char *x509_revoke_reason_flags[] = {
"unused",
"keyCompromise",
"cACompromise",
@@ -1855,30 +1926,30 @@ static const char *x509_revoke_reasons[] = {
"aACompromise",
};
static size_t x509_revoke_reasons_count =
sizeof(x509_revoke_reasons)/sizeof(x509_revoke_reasons[0]);
static size_t x509_revoke_reason_flags_count =
sizeof(x509_revoke_reason_flags)/sizeof(x509_revoke_reason_flags[0]);
const char *x509_revoke_reason_name(int flag)
const char *x509_revoke_reason_flag_name(int flag)
{
int i;
for (i = 0; i < x509_revoke_reasons_count; i++) {
for (i = 0; i < x509_revoke_reason_flags_count; i++) {
if (flag & 1) {
if (flag >> 1) {
error_print();
return NULL;
}
return x509_revoke_reasons[i];
return x509_revoke_reason_flags[i];
}
flag >>= 1;
}
return NULL;
}
int x509_revoke_reason_from_name(int *flag, const char *name)
int x509_revoke_reason_flag_from_name(int *flag, const char *name)
{
int i;
for (i = 0; i < x509_revoke_reasons_count; i++) {
if (strcmp(name, x509_revoke_reasons[i]) == 0) {
for (i = 0; i < x509_revoke_reason_flags_count; i++) {
if (strcmp(name, x509_revoke_reason_flags[i]) == 0) {
*flag = 1 << i;
return 1;
}
@@ -1888,104 +1959,59 @@ int x509_revoke_reason_from_name(int *flag, const char *name)
return -1;
}
int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int bits)
int x509_revoke_reason_flags_print(FILE *fp, int fmt, int ind, const char *label, int bits)
{
return asn1_bits_print(fp, fmt, ind, label, x509_revoke_reasons, x509_revoke_reasons_count, bits);
return asn1_bits_print(fp, fmt, ind, label, x509_revoke_reason_flags, x509_revoke_reason_flags_count, bits);
}
int x509_uri_as_general_names_to_der_ex(int tag, const char *uri, size_t urilen,
uint8_t **out, size_t *outlen)
{
int choice = X509_gn_uniform_resource_identifier;
size_t len = 0;
/*
Example CRLDistributionPoints extension
1 DistributionPoint in CRLDistributionPoints
distributionPoint choice: fullName
2 GeneralName in fullName(GeneralNames), same CRL with different URI
Extension
extnID: CRLDistributionPoints (2.5.29.31)
CRLDistributionPoints
DistributionPoint
distributionPoint
fullName
GeneralName
URI: http://mscrl.microsoft.com/pki/mscorp/crl/Microsoft%20RSA%20TLS%20CA%2002.crl
GeneralName
URI: http://crl.microsoft.com/pki/mscorp/crl/Microsoft%20RSA%20TLS%20CA%2002.crl
*/
if (!uri || !urilen) {
return 0;
}
if (x509_general_name_to_der(choice, (uint8_t *)uri, urilen, NULL, &len) != 1
|| asn1_sequence_header_to_der_ex(tag, len, out, outlen) != 1
|| x509_general_name_to_der(choice, (uint8_t *)uri, urilen, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_uri_as_distribution_point_name_to_der(const char *uri, size_t urilen,
uint8_t **out, size_t *outlen)
{
int ret;
if ((ret = x509_uri_as_general_names_to_der_ex(ASN1_TAG_EXPLICIT(0), uri, urilen, out, outlen)) != 1) {
error_print();
return -1;
if (ret < 0) error_print();
return ret;
}
return 1;
}
int x509_uri_as_explicit_distribution_point_name_to_der(int index,
const char *uri, size_t urilen, uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (!uri || !urilen) {
return 0;
}
if (x509_uri_as_distribution_point_name_to_der(uri, urilen, NULL, &len) != 1
|| asn1_explicit_header_to_der(index, len, out, outlen) != 1
|| x509_uri_as_distribution_point_name_to_der(uri, urilen, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_uri_as_distribution_point_to_der(const char *uri, size_t urilen, uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (!uri || !urilen) {
return 0;
}
if (x509_uri_as_explicit_distribution_point_name_to_der(0, uri, urilen, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| x509_uri_as_explicit_distribution_point_name_to_der(0, uri, urilen, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_distribution_points_to_der(const char *http_uri, size_t http_urilen,
const char *ldap_uri, size_t ldap_urilen, uint8_t **out, size_t *outlen)
{
size_t len = 0;
if ((!http_uri || !http_urilen) && (!ldap_uri || !ldap_urilen)) {
return 0;
}
if (x509_uri_as_distribution_point_to_der(http_uri, http_urilen, NULL, &len) < 0
|| x509_uri_as_distribution_point_to_der(ldap_uri, ldap_urilen, NULL, &len) < 0
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| x509_uri_as_distribution_point_to_der(http_uri, http_urilen, out, outlen) < 0
|| x509_uri_as_distribution_point_to_der(ldap_uri, ldap_urilen, out, outlen) < 0) {
error_print();
return -1;
}
return 1;
}
int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
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_any_type_from_der(&tag, d, dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return -1;
return ret;
}
switch (tag) {
case ASN1_TAG_EXPLICIT(0):
*choice = 0;
break;
case ASN1_TAG_EXPLICIT(1):
*choice = 1;
break;
default:
error_print();
@@ -1994,6 +2020,25 @@ int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t
return 1;
}
int x509_uri_as_distribution_point_name_from_der(const char **uri, size_t *urilen,
const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
int choice;
if ((ret = x509_distribution_point_name_from_der(&choice, &d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (choice == 0) {
*uri = (char *)d;
*urilen = dlen;
}
return 1;
}
int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
{
int tag;
@@ -2017,34 +2062,68 @@ int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *l
return 1;
}
// 这个如何使用?如何准备完整的数据呢?
int x509_distribution_point_to_der(
int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len,
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
uint8_t **out, size_t *outlen)
int x509_uri_as_explicit_distribution_point_name_to_der(int index,
const char *uri, size_t urilen, uint8_t **out, size_t *outlen)
{
/*
size_t len = 0;
if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0
|| asn1_implicit_bits_to_der(1, reasons, NULL, &len) < 0
|| asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, NULL, &len) < 0
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, out, outlen) < 0
|| asn1_implicit_bits_to_der(1, reasons, out, outlen) < 0
|| asn1_implicit_sequence_to_der(2, crl_issuer, crl_issuer_len, out, outlen) < 0) {
if (!uri || !urilen) {
return 0;
}
if (x509_uri_as_distribution_point_name_to_der(uri, urilen, NULL, &len) != 1
|| asn1_explicit_header_to_der(index, len, out, outlen) != 1
|| x509_uri_as_distribution_point_name_to_der(uri, urilen, out, outlen) != 1) {
error_print();
return -1;
}
*/
return 1;
}
int x509_distribution_point_from_der(
int *dist_point_choice, const uint8_t **dist_point, size_t *dist_point_len,
int x509_uri_as_explicit_distribution_point_name_from_der(int index,
const char **uri, size_t *urilen, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *a;
size_t alen;
if ((ret = asn1_explicit_from_der(index, &a, &alen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (x509_uri_as_distribution_point_name_from_der(uri, urilen, &a, &alen) != 1
|| asn1_length_is_zero(alen) != 1) {
error_print();
return -1;
}
return 1;
}
int x509_uri_as_distribution_point_to_der(const char *uri, size_t urilen,
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (!uri || !urilen) {
return 0;
}
if (x509_uri_as_explicit_distribution_point_name_to_der(0, uri, urilen, NULL, &len) != 1
|| x509_revoke_reason_flags_to_der(reasons, NULL, &len) < 0
|| x509_general_names_to_der(crl_issuer, crl_issuer_len, NULL, &len) < 0
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| x509_uri_as_explicit_distribution_point_name_to_der(0, uri, urilen, out, outlen) != 1
|| x509_revoke_reason_flags_to_der(reasons, out, outlen) < 0
|| x509_general_names_to_der(crl_issuer, crl_issuer_len, out, outlen) < 0) {
error_print();
return -1;
}
return 1;
}
int x509_uri_as_distribution_point_from_der(const char **uri, size_t *urilen,
int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len,
const uint8_t **in, size_t *inlen)
{
/*
int ret;
const uint8_t *d;
size_t dlen;
@@ -2053,14 +2132,13 @@ int x509_distribution_point_from_der(
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
|| asn1_implicit_bits_from_der(1, reasons, &d, &dlen) < 0
|| asn1_implicit_sequence_from_der(2, crl_issuer, crl_issuer_len, &d, &dlen) < 0
if (x509_uri_as_explicit_distribution_point_name_from_der(0, uri, urilen, &d, &dlen) != 1
|| x509_revoke_reason_flags_from_der(reasons, &d, &dlen) < 0
|| x509_general_names_from_der(crl_issuer, crl_issuer_len, &d, &dlen) < 0
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
*/
return 1;
}
@@ -2078,7 +2156,7 @@ int x509_distribution_point_print(FILE *fp, int fmt, int ind, const char *label,
if (ret) x509_distribution_point_name_print(fp, fmt, ind, "distributionPoint", p, len);
if ((ret = asn1_implicit_bits_from_der(1, &bits, &d, &dlen)) < 0) goto err;
if (ret) x509_revoke_reasons_print(fp, fmt, ind, "reasons", bits);
if (ret) x509_revoke_reason_flags_print(fp, fmt, ind, "reasons", bits);
if ((ret = asn1_implicit_sequence_from_der(2, &p, &len, &d, &dlen)) < 0) goto err;
if (ret) x509_general_names_print(fp, fmt, ind, "cRLIssuer", p, len);
@@ -2089,9 +2167,53 @@ err:
return -1;
}
int x509_distribution_points_validate(const uint8_t *d, size_t dlen)
int x509_uri_as_distribution_points_to_der(const char *uri, size_t urilen,
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
uint8_t **out, size_t *outlen)
{
return -1;
size_t len = 0;
if (!uri || !urilen) {
return 0;
}
if (x509_uri_as_distribution_point_to_der(uri, urilen,
reasons, crl_issuer, crl_issuer_len, NULL, &len) < 0
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| x509_uri_as_distribution_point_to_der(uri, urilen,
reasons, crl_issuer, crl_issuer_len, out, outlen) < 0) {
error_print();
return -1;
}
return 1;
}
int x509_uri_as_distribution_points_from_der(const char **uri, size_t *urilen,
int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len,
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 ret;
}
*uri = NULL;
*urilen = 0;
while (dlen) {
if (x509_uri_as_distribution_point_from_der(uri, urilen, reasons, crl_issuer, crl_issuer_len, &d, &dlen) != 1) {
error_print();
return -1;
}
if (*uri) {
return 1;
}
}
return 1;
}
int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)

View File

@@ -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.
@@ -229,51 +229,19 @@ int x509_req_sign(
return 1;
}
int x509_req_verify(const uint8_t *req, size_t reqlen, const SM2_KEY *sign_pubkey, const char *signer_id, size_t signer_id_len)
int x509_req_verify(const uint8_t *req, size_t reqlen, const char *signer_id, size_t signer_id_len)
{
int ret;
const uint8_t *d;
size_t dlen;
const uint8_t *p;
size_t len;
const uint8_t *req_info;
size_t req_info_len;
int signature_algor;
const uint8_t *sig;
size_t siglen;
SM2_SIGN_CTX sign_ctx;
SM2_KEY public_key;
if (asn1_sequence_from_der(&d, &dlen, &req, &reqlen) != 1
|| asn1_length_is_zero(reqlen) != 1) {
if (x509_req_get_details(req, reqlen, NULL, NULL, NULL, &public_key, NULL, NULL, NULL, NULL, NULL) != 1) {
error_print();
return -1;
}
req_info = d;
req_info_len = dlen;
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) {
if (x509_signed_verify(req, reqlen, &public_key, signer_id, signer_id_len) != 1) {
error_print();
return -1;
}
req_info_len -= dlen;
if (x509_signature_algor_from_der(&signature_algor, &d, &dlen) != 1
|| asn1_bit_octets_from_der(&sig, &siglen, &d, &dlen) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
if (signature_algor != OID_sm2sign_with_sm3) {
error_print();
return -1;
}
if (sm2_verify_init(&sign_ctx, sign_pubkey, signer_id, signer_id_len) != 1
|| sm2_verify_update(&sign_ctx, req_info, req_info_len) != 1
|| (ret = sm2_verify_finish(&sign_ctx, sig, siglen)) != 1) {
error_print();
return -1;
}
return ret;
return 1;
}
int x509_req_get_details(const uint8_t *req, size_t reqlen,
@@ -343,3 +311,50 @@ int x509_req_from_pem(uint8_t *req, size_t *reqlen, size_t maxlen, FILE *fp)
}
return 1;
}
#include <gmssl/file.h>
int x509_req_new_from_pem(uint8_t **out, size_t *outlen, FILE *fp)
{
uint8_t *req;
size_t reqlen;
size_t maxlen;
if (!out || !outlen || !fp) {
error_print();
return -1;
}
if (file_size(fp, &maxlen) != 1) {
error_print();
return -1;
}
if (!(req = malloc(maxlen))) {
error_print();
return -1;
}
if (x509_req_from_pem(req, &reqlen, maxlen, fp) != 1) {
free(req);
error_print();
return -1;
}
*out = req;
*outlen = reqlen;
return 1;
}
int x509_req_new_from_file(uint8_t **req, size_t *reqlen, const char *file)
{
FILE *fp = NULL;
if (!(fp = fopen(file, "rb"))) {
error_print();
return -1;
}
if (x509_req_new_from_pem(req, reqlen, fp) != 1) {
error_print();
fclose(fp);
return -1;
}
fclose(fp);
return 1;
}