mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
Update CRL related
to be continue ...
This commit is contained in:
@@ -278,8 +278,9 @@ int asn1_generalized_time_from_der_ex(int tag, time_t *tv, const uint8_t **in, s
|
|||||||
#define asn1_implicit_generalized_time_to_der(i,tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen)
|
#define asn1_implicit_generalized_time_to_der(i,tv,out,outlen) asn1_generalized_time_to_der_ex(ASN1_TAG_IMPLICIT(i),tv,out,outlen)
|
||||||
#define asn1_implicit_generalized_time_from_der(i,tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen)
|
#define asn1_implicit_generalized_time_from_der(i,tv,in,inlen) asn1_generalized_time_from_der_ex(ASN1_TAG_IMPLICIT(i),tv,in,inlen)
|
||||||
|
|
||||||
#define asn1_sequence_to_der(d,dlen,out,outlen) asn1_nonempty_type_to_der(ASN1_TAG_SEQUENCE,d,dlen,out,outlen)
|
// BasicConstraints might be an empty sequence in entity certificates
|
||||||
#define asn1_sequence_from_der(d,dlen,in,inlen) asn1_nonempty_type_from_der(ASN1_TAG_SEQUENCE,d,dlen,in,inlen)
|
#define asn1_sequence_to_der(d,dlen,out,outlen) asn1_type_to_der(ASN1_TAG_SEQUENCE,d,dlen,out,outlen)
|
||||||
|
#define asn1_sequence_from_der(d,dlen,in,inlen) asn1_type_from_der(ASN1_TAG_SEQUENCE,d,dlen,in,inlen)
|
||||||
#define asn1_implicit_sequence_to_der(i,d,dlen,out,outlen) asn1_nonempty_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen)
|
#define asn1_implicit_sequence_to_der(i,d,dlen,out,outlen) asn1_nonempty_type_to_der(ASN1_TAG_EXPLICIT(i),d,dlen,out,outlen)
|
||||||
#define asn1_implicit_sequence_from_der(i,d,dlen,in,inlen) asn1_nonempty_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen)
|
#define asn1_implicit_sequence_from_der(i,d,dlen,in,inlen) asn1_nonempty_type_from_der(ASN1_TAG_EXPLICIT(i),d,dlen,in,inlen)
|
||||||
|
|
||||||
@@ -305,6 +306,7 @@ int asn1_header_to_der(int tag, size_t dlen, uint8_t **out, size_t *outlen);
|
|||||||
|
|
||||||
#define asn1_octet_string_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_OCTET_STRING,dlen,out,outlen)
|
#define asn1_octet_string_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_OCTET_STRING,dlen,out,outlen)
|
||||||
|
|
||||||
|
#define asn1_sequence_header_to_der_ex(tag,dlen,out,outlen) asn1_header_to_der(tag,dlen,out,outlen)
|
||||||
#define asn1_sequence_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SEQUENCE,dlen,out,outlen)
|
#define asn1_sequence_header_to_der(dlen,out,outlen) asn1_header_to_der(ASN1_TAG_SEQUENCE,dlen,out,outlen)
|
||||||
#define asn1_implicit_sequence_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
|
#define asn1_implicit_sequence_header_to_der(i,dlen,out,outlen) asn1_header_to_der(ASN1_TAG_EXPLICIT(i),dlen,out,outlen)
|
||||||
|
|
||||||
|
|||||||
@@ -85,9 +85,11 @@ enum {
|
|||||||
OID_ce_freshest_crl,
|
OID_ce_freshest_crl,
|
||||||
OID_netscape_cert_type,
|
OID_netscape_cert_type,
|
||||||
OID_netscape_cert_comment,
|
OID_netscape_cert_comment,
|
||||||
OID_cert_authority_info_access,
|
|
||||||
OID_ct_precertificate_scts,
|
OID_ct_precertificate_scts,
|
||||||
|
|
||||||
|
OID_ad_ca_issuers,
|
||||||
|
OID_ad_ocsp,
|
||||||
|
|
||||||
// CRL Extensions
|
// CRL Extensions
|
||||||
//OID_ce_authority_key_identifier,
|
//OID_ce_authority_key_identifier,
|
||||||
//OID_ce_issuer_alt_name,
|
//OID_ce_issuer_alt_name,
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ int x509_exts_add_ext_key_usage(uint8_t *exts, size_t *extslen, size_t maxlen, i
|
|||||||
int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
|
int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
|
||||||
int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int skip_certs);
|
int x509_exts_add_inhibit_any_policy(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, int skip_certs);
|
||||||
int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
|
int x509_exts_add_freshest_crl(uint8_t *exts, size_t *extslen, size_t maxlen, int critical, const uint8_t *d, size_t dlen);
|
||||||
|
int x509_exts_add_authority_info_access(uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
|
||||||
|
const char *crt_uri, size_t crt_urilen, // crt_uri is the URI (http://examaple.com/subCA.crt) of DER-encoded CA cert
|
||||||
|
const char *ocsp_uri, size_t ocsp_urilen);
|
||||||
|
|
||||||
int x509_exts_add_sequence(uint8_t *exts, size_t *extslen, size_t maxlen,
|
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 oid, int critical, const uint8_t *d, size_t dlen);
|
||||||
@@ -466,6 +469,10 @@ DistributionPointName ::= CHOICE {
|
|||||||
fullName [0] IMPLICIT GeneralNames, -- SEQUENCE OF
|
fullName [0] IMPLICIT GeneralNames, -- SEQUENCE OF
|
||||||
nameRelativeToCRLIssuer [1] IMPLICIT RelativeDistinguishedName } -- SET OF
|
nameRelativeToCRLIssuer [1] IMPLICIT RelativeDistinguishedName } -- SET OF
|
||||||
*/
|
*/
|
||||||
|
int x509_uri_as_general_names_to_der_ex(int tag, const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
|
||||||
|
int x509_uri_as_distribution_point_name_to_der(const char *uri, size_t urilen, 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);
|
||||||
|
|
||||||
int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
|
int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen);
|
||||||
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 x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label,const uint8_t *a, size_t alen);
|
int x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label,const uint8_t *a, size_t alen);
|
||||||
@@ -480,6 +487,10 @@ DistributionPoint ::= SEQUENCE {
|
|||||||
reasons [1] IMPLICIT ReasonFlags OPTIONAL,
|
reasons [1] IMPLICIT ReasonFlags OPTIONAL,
|
||||||
cRLIssuer [2] IMPLICIT GeneralNames OPTIONAL }
|
cRLIssuer [2] IMPLICIT GeneralNames OPTIONAL }
|
||||||
*/
|
*/
|
||||||
|
int x509_uri_as_distribution_point_to_der(const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
|
||||||
|
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);
|
||||||
|
|
||||||
int x509_distribution_point_to_der(
|
int x509_distribution_point_to_der(
|
||||||
int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len,
|
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,
|
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
|
||||||
@@ -497,8 +508,7 @@ int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, si
|
|||||||
int dist_point_choice, const uint8_t *dist_point, size_t dist_point_len,
|
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);
|
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len);
|
||||||
int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
|
int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
|
||||||
#define x509_distribution_points_to_der(d,dlen,out,outlen) asn1_sequence_to_der(d,dlen,out,outlen)
|
|
||||||
#define x509_distribution_points_from_der(d,dlen,in,inlen) asn1_sequence_from_der(d,dlen,in,inlen)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
|
CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
|
||||||
@@ -544,6 +554,37 @@ int x509_netscape_cert_type_print(FILE *fp, int fmt, int ind, const char *label,
|
|||||||
int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
|
int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
|
||||||
int *path_len_constraints);
|
int *path_len_constraints);
|
||||||
|
|
||||||
|
/*
|
||||||
|
AuthorityInfoAccessSyntax ::= SEQUENCE OF AccessDescription
|
||||||
|
|
||||||
|
AccessDescription ::= SEQUENCE {
|
||||||
|
accessMethod OBJECT IDENTIFIER,
|
||||||
|
accessLocation GeneralName }
|
||||||
|
|
||||||
|
accessMethods:
|
||||||
|
OID_ad_ca_issuers
|
||||||
|
OID_ad_ocsp
|
||||||
|
*/
|
||||||
|
const char *x509_access_method_name(int oid);
|
||||||
|
int x509_access_method_from_name(const char *name);
|
||||||
|
int x509_access_method_to_der(int oid, uint8_t **out, size_t *outlen);
|
||||||
|
int x509_access_method_from_der(int *oid, const uint8_t **in, size_t *inlen);
|
||||||
|
|
||||||
|
int x509_access_description_to_der(int oid, const char *uri, size_t urilen, uint8_t **out, size_t *outlen);
|
||||||
|
int x509_access_description_from_der(int *oid, const char **uri, size_t *urilen, const uint8_t **in, size_t *inlen);
|
||||||
|
int x509_access_description_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
|
||||||
|
|
||||||
|
int x509_authority_info_access_to_der(
|
||||||
|
const char *crt_uri, size_t crt_urilen,
|
||||||
|
const char *ocsp_uri, size_t ocsp_urilen,
|
||||||
|
uint8_t **out, size_t *outlen);
|
||||||
|
int x509_authority_info_access_from_der(
|
||||||
|
const char **crt_uri, size_t *crt_urilen,
|
||||||
|
const char **ocsp_uri, size_t *ocsp_urilen,
|
||||||
|
const uint8_t **in, size_t *inlen);
|
||||||
|
int x509_authority_info_access_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -826,6 +826,7 @@ int x509_ext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t
|
|||||||
case OID_ce_freshest_crl: return x509_freshest_crl_print(fp, fmt, ind, name, p, len);
|
case OID_ce_freshest_crl: return x509_freshest_crl_print(fp, fmt, ind, name, p, len);
|
||||||
case OID_netscape_cert_type: return x509_netscape_cert_type_print(fp, fmt, ind, name, ival);
|
case OID_netscape_cert_type: return x509_netscape_cert_type_print(fp, fmt, ind, name, ival);
|
||||||
case OID_netscape_cert_comment: return format_string(fp, fmt, ind, name, p, len);
|
case OID_netscape_cert_comment: return format_string(fp, fmt, ind, name, p, len);
|
||||||
|
case OID_pe_authority_info_access: return x509_authority_info_access_print(fp, fmt, ind, name, p, len);
|
||||||
default: format_bytes(fp, fmt, ind, "extnValue", p, len);
|
default: format_bytes(fp, fmt, ind, "extnValue", p, len);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -525,6 +525,7 @@ int x509_issuing_distribution_point_to_der(
|
|||||||
int only_contains_attr_certs,
|
int only_contains_attr_certs,
|
||||||
uint8_t **out, size_t *outlen)
|
uint8_t **out, size_t *outlen)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0
|
if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &len) < 0
|
||||||
|| asn1_implicit_boolean_to_der(1, only_contains_user_certs, NULL, &len) < 0
|
|| asn1_implicit_boolean_to_der(1, only_contains_user_certs, NULL, &len) < 0
|
||||||
@@ -542,6 +543,7 @@ int x509_issuing_distribution_point_to_der(
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,6 +556,7 @@ int x509_issuing_distribution_point_from_der(
|
|||||||
int *only_contains_attr_certs,
|
int *only_contains_attr_certs,
|
||||||
const uint8_t **in, size_t *inlen)
|
const uint8_t **in, size_t *inlen)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
int ret;
|
int ret;
|
||||||
const uint8_t *d;
|
const uint8_t *d;
|
||||||
size_t dlen;
|
size_t dlen;
|
||||||
@@ -572,6 +575,7 @@ int x509_issuing_distribution_point_from_der(
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
498
src/x509_ext.c
498
src/x509_ext.c
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2014-2023 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
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
@@ -288,6 +288,13 @@ int x509_exts_add_crl_distribution_points(uint8_t *exts, size_t *extslen, size_t
|
|||||||
int critical, const uint8_t *d, size_t dlen)
|
int critical, const uint8_t *d, size_t dlen)
|
||||||
{
|
{
|
||||||
int oid = OID_ce_crl_distribution_points;
|
int oid = OID_ce_crl_distribution_points;
|
||||||
|
|
||||||
|
// The extension SHOULD be non-critical, but this profile
|
||||||
|
// RECOMMENDS support for this extension by CAs and applications.
|
||||||
|
if (critical) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
|
return x509_exts_add_sequence(exts, extslen, maxlen, oid, critical, d, dlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,11 +445,23 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeneralName CHOICE 中有的是基本类型,有的是SEQUENCE,在设置标签时是否有区别?
|
|
||||||
// 这里是否支持OPTIONAL??
|
|
||||||
int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
|
int x509_general_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
|
||||||
{
|
{
|
||||||
return asn1_implicit_to_der(choice, d, dlen, out, outlen);
|
switch (choice) {
|
||||||
|
case X509_gn_rfc822_name:
|
||||||
|
case X509_gn_dns_name:
|
||||||
|
case X509_gn_uniform_resource_identifier:
|
||||||
|
case X509_gn_ip_address:
|
||||||
|
if (asn1_implicit_to_der(choice, d, dlen, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
|
int x509_general_name_from_der(int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
|
||||||
@@ -1284,6 +1303,11 @@ int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t *
|
|||||||
if (ret < 0) error_print();
|
if (ret < 0) error_print();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if (!d || !dlen) {
|
||||||
|
*ca = -1;
|
||||||
|
*path_len_cons = -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (asn1_boolean_from_der(ca, &d, &dlen) < 0
|
if (asn1_boolean_from_der(ca, &d, &dlen) < 0
|
||||||
|| asn1_int_from_der(path_len_cons, &d, &dlen) < 0
|
|| asn1_int_from_der(path_len_cons, &d, &dlen) < 0
|
||||||
|| asn1_length_is_zero(dlen) != 1) {
|
|| asn1_length_is_zero(dlen) != 1) {
|
||||||
@@ -1294,18 +1318,32 @@ int x509_basic_constraints_from_der(int *ca, int *path_len_cons, const uint8_t *
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (*ca < 0) *ca = 0;
|
// from_der() MUST NOT set default value to *ca
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x509_basic_constraints_validate(int ca, int path_len_cons, int cert_type)
|
int x509_basic_constraints_validate(int ca, int path_len_cons, int cert_type)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
entity_cert:
|
||||||
|
ca = -1 or 0
|
||||||
|
path_len_constraints = -1
|
||||||
|
first_ca_cert:
|
||||||
|
ca = 1
|
||||||
|
path_len_constraints = 0
|
||||||
|
middle_ca_cert:
|
||||||
|
ca = 1
|
||||||
|
path_len_constraints = -1 or > 0
|
||||||
|
root_ca_cert:
|
||||||
|
ca = 1
|
||||||
|
path_len_constraints = -1 or > 0 (=0 might be ok?)
|
||||||
|
*/
|
||||||
if (cert_type == X509_cert_ca) {
|
if (cert_type == X509_cert_ca) {
|
||||||
if (ca != 1) {
|
if (ca != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (path_len_cons < 0 || path_len_cons > 6) {
|
if (path_len_cons < 0 || path_len_cons > 6) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1325,6 +1363,11 @@ int x509_basic_constraints_print(FILE *fp, int fmt, int ind, const char *label,
|
|||||||
format_print(fp, fmt, ind, "%s\n", label);
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
ind += 4;
|
ind += 4;
|
||||||
|
|
||||||
|
// BasicConstraints might be an empty sequence in entity certificates
|
||||||
|
if (!d || !dlen) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ret = asn1_boolean_from_der(&val, &d, &dlen)) < 0) goto err;
|
if ((ret = asn1_boolean_from_der(&val, &d, &dlen)) < 0) goto err;
|
||||||
if (ret) format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(val));
|
if (ret) format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(val));
|
||||||
else format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(0)); // 特殊对待,无论cA值是否编码均输出结果
|
else format_print(fp, fmt, ind, "cA: %s\n", asn1_boolean_name(0)); // 特殊对待,无论cA值是否编码均输出结果
|
||||||
@@ -1656,6 +1699,35 @@ int x509_ext_key_usage_print(FILE *fp, int fmt, int ind, const char *label, cons
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
CRL Distribution Points
|
||||||
|
|
||||||
|
* 假设证书的cRLIssuer和issuer一致,即签发证书的CA也签发了证书所属的CRL
|
||||||
|
不支持可选的cRLIssuer编码,解码时忽略cRLIssuer
|
||||||
|
编解、解码时均要求DistributionPoint中包含distributionPoint
|
||||||
|
|
||||||
|
* 如果证书扩展中不包含reasons,那么在CRL中必须包含完整的reasons。
|
||||||
|
证书扩展中包含reasons,逻辑上意味由不同的CRL包含因不同原因注销的证书,RFC不推荐这种方式
|
||||||
|
|
||||||
|
* 编码时最多支持2个DistributionPoint,分别用于HTTP和LDAP的URI
|
||||||
|
即DistributionPointName CHOICE GeneralNames,其中只有一个GeneralName CHOICE uri
|
||||||
|
|
||||||
|
* 解码时对每个解析成功的DistributionPoint的uri进行判断
|
||||||
|
最多返回一个http和一个ldap,其他协议的uri被忽略
|
||||||
|
|
||||||
|
* RFC要求每个DistributionPoint中至少包含一个HTTP或LDAP uri
|
||||||
|
|
||||||
|
* 解码时不支持DistributionPointName为nameRelativeToCRLIssuer
|
||||||
|
解码时DistributionPointName为(GeneralNames)fullName时,只返回第一个CHOICE为uri的GeneralName
|
||||||
|
|
||||||
|
* 当uri为HTTP时,CRL文件为DER编码
|
||||||
|
* 当uri为LDAP时
|
||||||
|
如 ldap://ldap.example.com/cn=example%20CA,dc=example,dc=com?certificateRevocationList;binary
|
||||||
|
如 ldap:///cn=example%20CA,dc=example,dc=com?certificateRevocationList;binary
|
||||||
|
必须包含 DN, certificateRevocationList, 应包含host部分
|
||||||
|
*/
|
||||||
|
|
||||||
static const char *x509_revoke_reasons[] = {
|
static const char *x509_revoke_reasons[] = {
|
||||||
"unused",
|
"unused",
|
||||||
"keyCompromise",
|
"keyCompromise",
|
||||||
@@ -1706,20 +1778,68 @@ int x509_revoke_reasons_print(FILE *fp, int fmt, int ind, const char *label, int
|
|||||||
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_reasons, x509_revoke_reasons_count, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
int x509_distribution_point_name_to_der(int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
|
int x509_uri_as_general_names_to_der_ex(int tag, const char *uri, size_t urilen,
|
||||||
|
uint8_t **out, size_t *outlen)
|
||||||
{
|
{
|
||||||
switch (choice) {
|
int choice = X509_gn_uniform_resource_identifier;
|
||||||
case 0:
|
size_t len = 0;
|
||||||
case 1:
|
if (x509_general_name_to_der(choice, (uint8_t *)uri, urilen, NULL, &len) != 1
|
||||||
if (asn1_implicit_to_der(choice, d, dlen, out, outlen) != 1) {
|
|| asn1_sequence_header_to_der_ex(tag, len, out, outlen) != 1
|
||||||
error_print();
|
|| x509_general_name_to_der(choice, (uint8_t *)uri, urilen, out, outlen) != 1) {
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
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)
|
||||||
|
{
|
||||||
|
if (x509_uri_as_general_names_to_der_ex(ASN1_TAG_EXPLICIT(0), uri, urilen, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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 (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 (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 (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)
|
||||||
@@ -1741,20 +1861,6 @@ int x509_distribution_point_name_from_der(int *choice, const uint8_t **d, size_t
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x509_explicit_distribution_point_name_to_der(int index, int choice, const uint8_t *d, size_t dlen, uint8_t **out, size_t *outlen)
|
|
||||||
{
|
|
||||||
// 注意:要能够解决d == NULL的情况
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x509_explicit_distribution_point_name_from_der(int index, int *choice, const uint8_t **d, size_t *dlen, const uint8_t **in, size_t *inlen)
|
|
||||||
{
|
|
||||||
// 注意:要能够解决d == NULL的情况
|
|
||||||
error_print();
|
|
||||||
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 x509_distribution_point_name_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen)
|
||||||
{
|
{
|
||||||
int tag;
|
int tag;
|
||||||
@@ -1783,6 +1889,7 @@ int x509_distribution_point_to_der(
|
|||||||
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
|
int reasons, const uint8_t *crl_issuer, size_t crl_issuer_len,
|
||||||
uint8_t **out, size_t *outlen)
|
uint8_t **out, size_t *outlen)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
if (x509_explicit_distribution_point_name_to_der(0, dist_point_choice, dist_point, dist_point_len, NULL, &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_bits_to_der(1, reasons, NULL, &len) < 0
|
||||||
@@ -1794,6 +1901,7 @@ int x509_distribution_point_to_der(
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1802,6 +1910,7 @@ int x509_distribution_point_from_der(
|
|||||||
int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len,
|
int *reasons, const uint8_t **crl_issuer, size_t *crl_issuer_len,
|
||||||
const uint8_t **in, size_t *inlen)
|
const uint8_t **in, size_t *inlen)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
int ret;
|
int ret;
|
||||||
const uint8_t *d;
|
const uint8_t *d;
|
||||||
size_t dlen;
|
size_t dlen;
|
||||||
@@ -1817,6 +1926,7 @@ int x509_distribution_point_from_der(
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1845,34 +1955,6 @@ err:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
extnID: CRLDistributionPoints (2.5.29.31)
|
|
||||||
DistributionPoint
|
|
||||||
distributionPoint
|
|
||||||
fullName
|
|
||||||
GeneralName
|
|
||||||
URI: http://www.rootca.gov.cn/Civil_Servant_arl/Civil_Servant_ARL.crl
|
|
||||||
DistributionPoint
|
|
||||||
distributionPoint
|
|
||||||
fullName
|
|
||||||
GeneralName
|
|
||||||
URI: ldap://ldap.rootca.gov.cn:390/CN=Civil_Servant_ARL,OU=ARL,O=NRCAC,C=CN
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
int x509_distribution_points_add_url(uint8_t *d, size_t *dlen, size_t maxlen, const char *url)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x509_distribution_points_add_distribution_point(uint8_t *d, size_t *dlen, size_t maxlen,
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int x509_distribution_points_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
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;
|
const uint8_t *p;
|
||||||
@@ -1992,4 +2074,304 @@ int x509_exts_validate(const uint8_t *exts, size_t extslen, int cert_type,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuthorityInfoAccess Extension
|
||||||
|
|
||||||
|
static uint32_t oid_ad_ocsp[] = { oid_ad,1 };
|
||||||
|
static uint32_t oid_ad_ca_issuers[] = { oid_ad,2 };
|
||||||
|
|
||||||
|
#define cnt(oid) (sizeof(oid)/sizeof((oid)[0]))
|
||||||
|
|
||||||
|
static const ASN1_OID_INFO access_methods[] = {
|
||||||
|
{ OID_ad_ocsp, "OCSP", oid_ad_ocsp, oid_cnt(oid_ad_ocsp) },
|
||||||
|
{ OID_ad_ca_issuers, "CAIssuers", oid_ad_ca_issuers, oid_cnt(oid_ad_ca_issuers) },
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *x509_access_method_name(int oid)
|
||||||
|
{
|
||||||
|
const ASN1_OID_INFO *info;
|
||||||
|
if (!(info = asn1_oid_info_from_oid(access_methods, cnt(access_methods), oid))) {
|
||||||
|
error_print();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return info->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_access_method_from_name(const char *name)
|
||||||
|
{
|
||||||
|
const ASN1_OID_INFO *info;
|
||||||
|
if (!(info = asn1_oid_info_from_name(access_methods, cnt(access_methods), name))) {
|
||||||
|
error_print();
|
||||||
|
return OID_undef;
|
||||||
|
}
|
||||||
|
return info->oid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_access_method_to_der(int oid, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
const ASN1_OID_INFO *info;
|
||||||
|
if (!(info = asn1_oid_info_from_oid(access_methods, cnt(access_methods), oid))) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asn1_object_identifier_to_der(info->nodes, info->nodes_cnt, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_access_method_from_der(int *oid, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
const ASN1_OID_INFO *info;
|
||||||
|
uint32_t nodes[32];
|
||||||
|
size_t nodes_cnt;
|
||||||
|
|
||||||
|
if ((ret = asn1_oid_info_from_der_ex(&info, nodes, &nodes_cnt, access_methods, cnt(access_methods), in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
else *oid = -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*oid = info->oid;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// currently AccessDescription not support values of SubjectInfoAccess extension
|
||||||
|
int x509_access_description_to_der(int oid, const char *uri, size_t urilen, uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
const int uri_choice = X509_gn_uniform_resource_identifier;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (oid != OID_ad_ocsp && oid != OID_ad_ca_issuers) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!uri || !urilen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (x509_access_method_to_der(oid, NULL, &len) != 1
|
||||||
|
|| x509_general_name_to_der(uri_choice, (const uint8_t *)uri, urilen, NULL, &len) != 1
|
||||||
|
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
||||||
|
|| x509_access_method_to_der(oid, out, outlen) != 1
|
||||||
|
|| x509_general_name_to_der(uri_choice, (const uint8_t *)uri, urilen, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_access_description_from_der(int *oid, const char **uri, size_t *urilen, const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
const uint8_t *d;
|
||||||
|
size_t dlen;
|
||||||
|
int uri_choice;
|
||||||
|
|
||||||
|
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
else {
|
||||||
|
*oid = -1;
|
||||||
|
*uri = NULL;
|
||||||
|
*urilen = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (x509_access_method_from_der(oid, &d, &dlen) != 1
|
||||||
|
|| x509_general_name_from_der(&uri_choice, (const uint8_t **)uri, urilen, &d, &dlen) != 1
|
||||||
|
|| asn1_length_is_zero(dlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (uri_choice != X509_gn_uniform_resource_identifier) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*uri == NULL || *urilen == 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_access_description_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
|
||||||
|
{
|
||||||
|
int oid;
|
||||||
|
int choice;
|
||||||
|
const uint8_t *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
|
ind += 4;
|
||||||
|
|
||||||
|
if (x509_access_method_from_der(&oid, &d, &dlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
format_print(fp, fmt, ind, "accessMethod: %s\n", x509_access_method_name(oid));
|
||||||
|
|
||||||
|
if (x509_general_name_from_der(&choice, &p, &len, &d, &dlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
x509_general_name_print(fp, fmt, ind, "GeneralName", choice, p, len);
|
||||||
|
|
||||||
|
if (dlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_authority_info_access_to_der(
|
||||||
|
const char *crt_uri, size_t crt_urilen,
|
||||||
|
const char *ocsp_uri, size_t ocsp_urilen,
|
||||||
|
uint8_t **out, size_t *outlen)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (crt_uri && crt_urilen) {
|
||||||
|
if (x509_access_description_to_der(OID_ad_ca_issuers, crt_uri, crt_urilen, NULL, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ocsp_uri && ocsp_urilen) {
|
||||||
|
if (x509_access_description_to_der(OID_ad_ocsp, ocsp_uri, ocsp_urilen, NULL, &len) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!len) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (asn1_sequence_header_to_der(len, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (crt_uri && crt_urilen) {
|
||||||
|
if (x509_access_description_to_der(OID_ad_ca_issuers, crt_uri, crt_urilen, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ocsp_uri && ocsp_urilen) {
|
||||||
|
if (x509_access_description_to_der(OID_ad_ocsp, ocsp_uri, ocsp_urilen, out, outlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_authority_info_access_from_der(
|
||||||
|
const char **crt_uri, size_t *crt_urilen,
|
||||||
|
const char **ocsp_uri, size_t *ocsp_urilen,
|
||||||
|
const uint8_t **in, size_t *inlen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
const uint8_t *d;
|
||||||
|
size_t dlen;
|
||||||
|
const uint8_t *ad;
|
||||||
|
size_t adlen;
|
||||||
|
|
||||||
|
if (!crt_uri || !crt_urilen || !ocsp_uri || !ocsp_urilen || !in || !(*in) || !inlen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*crt_uri = NULL;
|
||||||
|
*crt_urilen = 0;
|
||||||
|
*ocsp_uri = NULL;
|
||||||
|
*ocsp_urilen = 0;
|
||||||
|
|
||||||
|
if ((ret = asn1_sequence_of_from_der(&d, &dlen, in, inlen)) != 1) {
|
||||||
|
if (ret < 0) error_print();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dlen) {
|
||||||
|
int oid;
|
||||||
|
const char *uri;
|
||||||
|
size_t urilen;
|
||||||
|
|
||||||
|
if (x509_access_description_from_der(&oid, &uri, &urilen, &d, &dlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
switch (oid) {
|
||||||
|
case OID_ad_ca_issuers:
|
||||||
|
if (*crt_uri) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*crt_uri = uri;
|
||||||
|
*crt_urilen = urilen;
|
||||||
|
break;
|
||||||
|
case OID_ad_ocsp:
|
||||||
|
if (*ocsp_uri) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*ocsp_uri = uri;
|
||||||
|
*ocsp_urilen = urilen;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_authority_info_access_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_access_description_print(fp, fmt, ind, "AccessDescription", p, len);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x509_exts_add_authority_info_access(uint8_t *exts, size_t *extslen, size_t maxlen, int critical,
|
||||||
|
const char *crt_uri, size_t crt_urilen, const char *ocsp_uri, size_t ocsp_urilen)
|
||||||
|
{
|
||||||
|
int oid = OID_pe_authority_info_access;
|
||||||
|
size_t curlen = *extslen;
|
||||||
|
uint8_t val[256];
|
||||||
|
uint8_t *p = val;
|
||||||
|
size_t vlen = 0;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
// Conforming CAs MUST mark this extension as non-critical.
|
||||||
|
if (critical == 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (x509_authority_info_access_to_der(crt_uri, crt_urilen, ocsp_uri, ocsp_urilen, NULL, &len) != 1
|
||||||
|
|| asn1_length_le(len, sizeof(val)) != 1
|
||||||
|
|| x509_authority_info_access_to_der(crt_uri, crt_urilen, ocsp_uri, ocsp_urilen, &p, &vlen) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
exts += *extslen;
|
||||||
|
if (x509_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) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ static uint32_t oid_ce_certificate_issuer[] = { oid_ce,29 }; // crl_entry_ext
|
|||||||
#define OID_CE_CNT sizeof(oid_ce_subject_directory_attributes)/sizeof(int)
|
#define OID_CE_CNT sizeof(oid_ce_subject_directory_attributes)/sizeof(int)
|
||||||
static uint32_t oid_netscape_cert_type[] = { 2,16,840,1,113730,1,1 };
|
static uint32_t oid_netscape_cert_type[] = { 2,16,840,1,113730,1,1 };
|
||||||
static uint32_t oid_netscape_cert_comment[] = { 2,16,840,1,113730,1,13 };
|
static uint32_t oid_netscape_cert_comment[] = { 2,16,840,1,113730,1,13 };
|
||||||
static uint32_t oid_cert_authority_info_access[] = { 1,3,6,1,5,5,7,1,1 };
|
static uint32_t oid_pe_authority_info_access[] = { 1,3,6,1,5,5,7,1,1 };
|
||||||
static uint32_t oid_ct_precertificate_scts[] = { 1,3,6,1,4,1,11129,2,4,2 };
|
static uint32_t oid_ct_precertificate_scts[] = { 1,3,6,1,4,1,11129,2,4,2 };
|
||||||
|
|
||||||
static const ASN1_OID_INFO x509_ext_ids[] = {
|
static const ASN1_OID_INFO x509_ext_ids[] = {
|
||||||
@@ -158,7 +158,7 @@ static const ASN1_OID_INFO x509_ext_ids[] = {
|
|||||||
{ OID_ce_certificate_issuer, "CertificateIssuer", oid_ce_certificate_issuer, OID_CE_CNT },
|
{ OID_ce_certificate_issuer, "CertificateIssuer", oid_ce_certificate_issuer, OID_CE_CNT },
|
||||||
{ OID_netscape_cert_type, "NetscapeCertType", oid_netscape_cert_type, sizeof(oid_netscape_cert_type)/sizeof(int) },
|
{ OID_netscape_cert_type, "NetscapeCertType", oid_netscape_cert_type, sizeof(oid_netscape_cert_type)/sizeof(int) },
|
||||||
{ OID_netscape_cert_comment, "NetscapeCertComment", oid_netscape_cert_comment, sizeof(oid_netscape_cert_comment)/sizeof(int) },
|
{ OID_netscape_cert_comment, "NetscapeCertComment", oid_netscape_cert_comment, sizeof(oid_netscape_cert_comment)/sizeof(int) },
|
||||||
{ OID_cert_authority_info_access, "CertificateAuthorityInformationAccess", oid_cert_authority_info_access, sizeof(oid_cert_authority_info_access)/sizeof(int) },
|
{ OID_pe_authority_info_access, "AuthorityInformationAccess", oid_pe_authority_info_access, sizeof(oid_pe_authority_info_access)/sizeof(int) },
|
||||||
{ OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) },
|
{ OID_ct_precertificate_scts, "CT-PrecertificateSCTs", oid_ct_precertificate_scts, sizeof(oid_ct_precertificate_scts)/sizeof(int) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
static const char *options =
|
static const char *options =
|
||||||
"[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num "
|
"[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num "
|
||||||
"-key file [-pass pass] "
|
"-key file [-pass pass] "
|
||||||
"[-key_usage str]* [-out file]";
|
"[-key_usage str]* [-ocsp uri] [-crl uri] [-out file]";
|
||||||
|
|
||||||
|
|
||||||
static int ext_key_usage_set(int *usages, const char *usage_name)
|
static int ext_key_usage_set(int *usages, const char *usage_name)
|
||||||
@@ -49,6 +49,8 @@ int certgen_main(int argc, char **argv)
|
|||||||
char *common_name = NULL;
|
char *common_name = NULL;
|
||||||
int days = 0;
|
int days = 0;
|
||||||
int key_usage = 0;
|
int key_usage = 0;
|
||||||
|
char *ocsp = NULL;
|
||||||
|
char *crl = NULL;
|
||||||
char *keyfile = NULL;
|
char *keyfile = NULL;
|
||||||
char *pass = NULL;
|
char *pass = NULL;
|
||||||
char *outfile = NULL;
|
char *outfile = NULL;
|
||||||
@@ -112,6 +114,12 @@ int certgen_main(int argc, char **argv)
|
|||||||
fprintf(stderr, "%s: invalid -key_usage value '%s'\n", prog, usage);
|
fprintf(stderr, "%s: invalid -key_usage value '%s'\n", prog, usage);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
} else if (!strcmp(*argv, "-ocsp")) {
|
||||||
|
if (--argc < 1) goto bad;
|
||||||
|
ocsp = *(++argv);
|
||||||
|
} else if (!strcmp(*argv, "-crl")) {
|
||||||
|
if (--argc < 1) goto bad;
|
||||||
|
crl = *(++argv);
|
||||||
} else if (!strcmp(*argv, "-key")) {
|
} else if (!strcmp(*argv, "-key")) {
|
||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
keyfile = *(++argv);
|
keyfile = *(++argv);
|
||||||
@@ -173,6 +181,13 @@ bad:
|
|||||||
fprintf(stderr, "%s: inner error\n", prog);
|
fprintf(stderr, "%s: inner error\n", prog);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
if (ocsp) {
|
||||||
|
if (x509_exts_add_authority_info_access(exts, &extslen, sizeof(exts), 0,
|
||||||
|
ocsp, strlen(ocsp), crl, strlen(crl)) != 1) {
|
||||||
|
fprintf(stderr, "%s: error\n", prog);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
time(¬_before);
|
time(¬_before);
|
||||||
if (rand_bytes(serial, sizeof(serial)) != 1
|
if (rand_bytes(serial, sizeof(serial)) != 1
|
||||||
|
|||||||
Reference in New Issue
Block a user