mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-09-24 22:33:45 +08:00
Update X.509 Extensions
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
342
src/x509_ext.c
342
src/x509_ext.c
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user