"BUILD_CA_CERT",
"BUILD_CERT",
"BUILD_CRL_DISTRIBUTION_POINTS",
- "BUILD_CRL_ISSUER",
"BUILD_OCSP_ACCESS_LOCATIONS",
"BUILD_PATHLEN",
"BUILD_PERMITTED_NAME_CONSTRAINTS",
BUILD_CA_CERT,
/** a certificate, certificate_t* */
BUILD_CERT,
- /** CRL distribution point URIs, linked_list_t* containing char* */
+ /** CRL distribution point URIs, x509_cdp_t* */
BUILD_CRL_DISTRIBUTION_POINTS,
- /** CRL issuer for all distribution points follow up, identification_t* */
- BUILD_CRL_ISSUER,
/** OCSP AuthorityInfoAccess locations, linked_list_t* containing char* */
BUILD_OCSP_ACCESS_LOCATIONS,
/** certificate path length constraint */
typedef struct x509_t x509_t;
typedef struct x509_cert_policy_t x509_cert_policy_t;
typedef struct x509_policy_mapping_t x509_policy_mapping_t;
+typedef struct x509_cdp_t x509_cdp_t;
typedef enum x509_flag_t x509_flag_t;
/**
};
/**
+ * X.509 CRL distributionPoint
+ */
+struct x509_cdp_t {
+ /** CDP URI, as string */
+ char *uri;
+ /** CRL issuer */
+ identification_t *issuer;
+};
+
+/**
* X.509 certificate interface.
*
* This interface adds additional methods to the certificate_t type to
/**
* Create an enumerator over all CRL URIs and CRL Issuers.
*
- * @return enumerator over URIs (char*, identificiation_t*)
+ * @return enumerator over x509_cdp_t
*/
enumerator_t* (*create_crl_uri_enumerator)(x509_t *this);
linked_list_t *issuerAltNames;
/**
- * List of CRL URIs, as crl_uri_t
+ * List of CRL URIs, as x509_cdp_t
*/
linked_list_t *crl_uris;
};
/**
- * CRL URIs with associated issuer
- */
-typedef struct {
- identification_t *issuer;
- linked_list_t *uris;
-} crl_uri_t;
-
-/**
- * Create a new issuer entry
- */
-static crl_uri_t *crl_uri_create()
-{
- crl_uri_t *this;
-
- INIT(this,
- .uris = linked_list_create(),
- );
- return this;
-}
-
-/**
* Destroy a CRL URI struct
*/
-static void crl_uri_destroy(crl_uri_t *this)
+static void crl_uri_destroy(x509_cdp_t *this)
{
- this->uris->destroy_function(this->uris, free);
+ free(this->uri);
DESTROY_IF(this->issuer);
free(this);
}
return this->subjectAltNames->create_enumerator(this->subjectAltNames);
}
-/**
- * Convert enumerator value from entry to (uri, issuer)
- */
-static bool crl_enum_filter(identification_t *issuer_in,
- char **uri_in, char **uri_out,
- void *none_in, identification_t **issuer_out)
-{
- *uri_out = *uri_in;
- if (issuer_out)
- {
- *issuer_out = issuer_in;
- }
- return TRUE;
-}
-
-/**
- * Create inner enumerator over URIs
- */
-static enumerator_t *crl_enum_create(crl_uri_t *entry)
-{
- return enumerator_create_filter(entry->uris->create_enumerator(entry->uris),
- (void*)crl_enum_filter, entry->issuer, NULL);
-}
-
METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
private_openssl_x509_t *this)
{
- return enumerator_create_nested(
- this->crl_uris->create_enumerator(this->crl_uris),
- (void*)crl_enum_create, NULL, NULL);
+ return this->crl_uris->create_enumerator(this->crl_uris);
}
METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
{
CRL_DIST_POINTS *cdps;
DIST_POINT *cdp;
- identification_t *id;
+ identification_t *id, *issuer;
+ x509_cdp_t *entry;
char *uri;
- int i, j, point_num, name_num;
+ int i, j, k, point_num, name_num, issuer_num;
cdps = X509V3_EXT_d2i(ext);
if (!cdps)
cdp = sk_DIST_POINT_value(cdps, i);
if (cdp)
{
- crl_uri_t *entry;
-
- entry = crl_uri_create();
- this->crl_uris->insert_last(this->crl_uris, entry);
-
if (cdp->distpoint && cdp->distpoint->type == 0 &&
cdp->distpoint->name.fullname)
{
{
if (asprintf(&uri, "%Y", id) > 0)
{
- entry->uris->insert_last(entry->uris, uri);
+ if (cdp->CRLissuer)
+ {
+ issuer_num = sk_GENERAL_NAME_num(cdp->CRLissuer);
+ for (k = 0; k < issuer_num; k++)
+ {
+ issuer = general_name2id(
+ sk_GENERAL_NAME_value(cdp->CRLissuer, k));
+ if (issuer)
+ {
+ INIT(entry,
+ .uri = strdup(uri),
+ .issuer = issuer,
+ );
+ this->crl_uris->insert_last(
+ this->crl_uris, entry);
+ }
+ }
+ free(uri);
+ }
+ else
+ {
+ INIT(entry,
+ .uri = uri,
+ );
+ this->crl_uris->insert_last(this->crl_uris, entry);
+ }
}
id->destroy(id);
}
}
}
- if (cdp->CRLissuer)
- {
- name_num = sk_GENERAL_NAME_num(cdp->CRLissuer);
- for (j = 0; j < name_num; j++)
- {
- id = general_name2id(sk_GENERAL_NAME_value(cdp->CRLissuer, j));
- if (id)
- { /* get only one */
- entry->issuer = id;
- break;
- }
- }
- }
+
DIST_POINT_free(cdp);
}
}
auth_cfg_t *auth)
{
cert_validation_t valid = VALIDATION_SKIPPED;
- identification_t *id;
certificate_t *best = NULL;
+ identification_t *id;
+ x509_cdp_t *cdp;
bool uri_found = FALSE;
certificate_t *current;
enumerator_t *enumerator;
chunk_t chunk;
- char *uri;
/* use issuers subjectKeyIdentifier to find a cached CRL / fetch from CDP */
chunk = issuer->get_subjectKeyIdentifier(issuer);
/* find a cached CRL or fetch via configured CDP via CRLIssuer */
enumerator = subject->create_crl_uri_enumerator(subject);
while (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED &&
- enumerator->enumerate(enumerator, &uri, &id))
+ enumerator->enumerate(enumerator, &cdp))
{
if (id)
{
- valid = find_crl(subject, id, auth, &best, &uri_found);
+ valid = find_crl(subject, cdp->issuer, auth, &best, &uri_found);
}
}
enumerator->destroy(enumerator);
if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
{
enumerator = subject->create_crl_uri_enumerator(subject);
- while (enumerator->enumerate(enumerator, &uri, &id))
+ while (enumerator->enumerate(enumerator, &cdp))
{
uri_found = TRUE;
- current = fetch_crl(uri);
+ current = fetch_crl(cdp->uri);
if (current)
{
- if (id && !current->has_issuer(current, id))
+ if (cdp->issuer && !current->has_issuer(current, cdp->issuer))
{
DBG1(DBG_CFG, "issuer of fetched CRL '%Y' does not match "
"certificates CRL issuer '%Y'",
- current->get_issuer(current), id);
+ current->get_issuer(current), cdp->issuer);
current->destroy(current);
continue;
}
linked_list_t *subjectAltNames;
/**
- * List of crlDistributionPoints as crl_uri_t
+ * List of crlDistributionPoints as x509_cdp_t*
*/
linked_list_t *crl_uris;
);
/**
- * CRL URIs with associated issuer
+ * Destroy a CertificateDistributionPoint
*/
-typedef struct {
- identification_t *issuer;
- linked_list_t *uris;
-} crl_uri_t;
-
-/**
- * Create a new issuer entry
- */
-static crl_uri_t *crl_uri_create(identification_t *issuer)
-{
- crl_uri_t *this;
-
- INIT(this,
- .issuer = issuer ? issuer->clone(issuer) : NULL,
- .uris = linked_list_create(),
- );
- return this;
-}
-
-/**
- * Destroy a CRL URI struct
- */
-static void crl_uri_destroy(crl_uri_t *this)
+static void crl_uri_destroy(x509_cdp_t *this)
{
- this->uris->destroy_function(this->uris, free);
+ free(this->uri);
DESTROY_IF(this->issuer);
free(this);
}
#define CRL_DIST_POINTS_ISSUER 10
/**
+ * Add entry to the list of each pairing of URI and Issuer
+ */
+static void add_cdps(linked_list_t *list, linked_list_t *uris,
+ linked_list_t *issuers)
+{
+ identification_t *issuer, *id;
+ enumerator_t *enumerator;
+ x509_cdp_t *cdp;
+ char *uri;
+
+ while (uris->remove_last(uris, (void**)&id) == SUCCESS)
+ {
+ if (asprintf(&uri, "%Y", id) > 0)
+ {
+ if (issuers->get_count(issuers))
+ {
+ enumerator = issuers->create_enumerator(issuers);
+ while (enumerator->enumerate(enumerator, &issuer))
+ {
+ INIT(cdp,
+ .uri = strdup(uri),
+ .issuer = issuer->clone(issuer),
+ );
+ list->insert_last(list, cdp);
+ }
+ enumerator->destroy(enumerator);
+ free(uri);
+ }
+ else
+ {
+ INIT(cdp,
+ .uri = uri,
+ );
+ list->insert_last(list, cdp);
+ }
+ }
+ id->destroy(id);
+ }
+ while (issuers->remove_last(issuers, (void**)&id) == SUCCESS)
+ {
+ id->destroy(id);
+ }
+}
+
+/**
* Extracts one or several crlDistributionPoints into a list
*/
-static void parse_crlDistributionPoints(chunk_t blob, int level0,
- private_x509_cert_t *this)
+void x509_parse_crlDistributionPoints(chunk_t blob, int level0,
+ linked_list_t *list)
{
+ linked_list_t *uris, *issuers;
asn1_parser_t *parser;
chunk_t object;
int objectID;
- crl_uri_t *entry = NULL;
- identification_t *id;
- char *uri;
- linked_list_t *list = linked_list_create();
+ uris = linked_list_create();
+ issuers = linked_list_create();
parser = asn1_parser_create(crlDistributionPointsObjects, blob);
parser->set_top_level(parser, level0);
switch (objectID)
{
case CRL_DIST_POINTS:
- entry = crl_uri_create(NULL);
- this->crl_uris->insert_last(this->crl_uris, entry);
+ add_cdps(list, uris, issuers);
break;
case CRL_DIST_POINTS_FULLNAME:
- if (entry)
- {
- x509_parse_generalNames(object, parser->get_level(parser)+1,
- TRUE, list);
- while (list->remove_last(list, (void**)&id) == SUCCESS)
- {
- if (asprintf(&uri, "%Y", id) > 0)
- {
- entry->uris->insert_last(entry->uris, uri);
- }
- id->destroy(id);
- }
- }
+ x509_parse_generalNames(object, parser->get_level(parser) + 1,
+ TRUE, uris);
break;
case CRL_DIST_POINTS_ISSUER:
- if (entry)
- {
- x509_parse_generalNames(object, parser->get_level(parser)+1,
- TRUE, list);
- while (list->remove_last(list, (void**)&id) == SUCCESS)
- {
- if (!entry->issuer)
- {
- entry->issuer = id;
- }
- else
- {
- id->destroy(id);
- }
- }
- }
+ x509_parse_generalNames(object, parser->get_level(parser) + 1,
+ TRUE, issuers);
+ break;
+ default:
break;
}
}
parser->destroy(parser);
- list->destroy(list);
+
+ add_cdps(list, uris, issuers);
+
+ uris->destroy(uris);
+ issuers->destroy(issuers);
}
/**
parse_basicConstraints(object, level, this);
break;
case OID_CRL_DISTRIBUTION_POINTS:
- parse_crlDistributionPoints(object, level, this);
+ x509_parse_crlDistributionPoints(object, level,
+ this->crl_uris);
break;
case OID_AUTHORITY_KEY_ID:
this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
return this->ocsp_uris->create_enumerator(this->ocsp_uris);
}
-/**
- * Convert enumerator value from entry to (uri, issuer)
- */
-static bool crl_enum_filter(identification_t *issuer_in,
- char **uri_in, char **uri_out,
- void *none_in, identification_t **issuer_out)
-{
- *uri_out = *uri_in;
- if (issuer_out)
- {
- *issuer_out = issuer_in;
- }
- return TRUE;
-}
-
-/**
- * Create inner enumerator over URIs
- */
-static enumerator_t *crl_enum_create(crl_uri_t *entry)
-{
- return enumerator_create_filter(entry->uris->create_enumerator(entry->uris),
- (void*)crl_enum_filter, entry->issuer, NULL);
-}
-
METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
private_x509_cert_t *this)
{
- return enumerator_create_nested(
- this->crl_uris->create_enumerator(this->crl_uris),
- (void*)crl_enum_create, NULL, NULL);
+ return this->crl_uris->create_enumerator(this->crl_uris);
}
METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
chunk_t policyConstraints = chunk_empty;
identification_t *issuer, *subject;
- crl_uri_t *entry;
+ x509_cdp_t *cdp;
chunk_t key_info;
signature_scheme_t scheme;
hasher_t *hasher;
- enumerator_t *enumerator, *uris;
+ enumerator_t *enumerator;
char *uri;
subject = cert->subject;
/* encode CRL distribution points extension */
enumerator = cert->crl_uris->create_enumerator(cert->crl_uris);
- while (enumerator->enumerate(enumerator, &entry))
+ while (enumerator->enumerate(enumerator, &cdp))
{
- chunk_t distributionPoint, gn;
- chunk_t crlIssuer = chunk_empty, gns = chunk_empty;
+ chunk_t distributionPoint, crlIssuer = chunk_empty;
- if (entry->issuer)
+ if (cdp->issuer)
{
crlIssuer = asn1_wrap(ASN1_CONTEXT_C_2, "m",
- build_generalName(entry->issuer));
+ build_generalName(cdp->issuer));
}
- uris = entry->uris->create_enumerator(entry->uris);
- while (uris->enumerate(uris, &uri))
- {
- gn = asn1_wrap(ASN1_CONTEXT_S_6, "c", chunk_create(uri, strlen(uri)));
- gns = chunk_cat("mm", gns, gn);
- }
- uris->destroy(uris);
-
distributionPoint = asn1_wrap(ASN1_SEQUENCE, "mm",
- asn1_wrap(ASN1_CONTEXT_C_0, "m",
- asn1_wrap(ASN1_CONTEXT_C_0, "m", gns)),
- crlIssuer);
+ asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_CONTEXT_C_0, "m",
+ asn1_wrap(ASN1_CONTEXT_S_6, "c",
+ chunk_create(cdp->uri, strlen(cdp->uri))))),
+ crlIssuer);
crlDistributionPoints = chunk_cat("mm", crlDistributionPoints,
distributionPoint);
}
private_x509_cert_t *cert;
certificate_t *sign_cert = NULL;
private_key_t *sign_key = NULL;
- identification_t *crl_issuer = NULL;
hash_algorithm_t digest_alg = HASH_SHA1;
cert = create_empty();
{
enumerator_t *enumerator;
linked_list_t *list;
- crl_uri_t *entry;
- char *uri;
+ x509_cdp_t *in, *cdp;
list = va_arg(args, linked_list_t*);
- if (list->get_count(list))
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &in))
{
- entry = crl_uri_create(crl_issuer);
- enumerator = list->create_enumerator(list);
- while (enumerator->enumerate(enumerator, &uri))
- {
- entry->uris->insert_last(entry->uris, strdup(uri));
- }
- enumerator->destroy(enumerator);
- cert->crl_uris->insert_last(cert->crl_uris, entry);
+ INIT(cdp,
+ .uri = strdup(in->uri),
+ .issuer = in->issuer ? in->issuer->clone(in->issuer) : NULL,
+ );
+ cert->crl_uris->insert_last(cert->crl_uris, cdp);
}
- continue;
- }
- case BUILD_CRL_ISSUER:
- {
- crl_issuer = va_arg(args, identification_t*);
+ enumerator->destroy(enumerator);
continue;
}
case BUILD_OCSP_ACCESS_LOCATIONS:
}
/**
+ * Free a CRL DistributionPoint
+ */
+static void destroy_cdp(x509_cdp_t *this)
+{
+ DESTROY_IF(this->issuer);
+ free(this);
+}
+
+/**
* Issue a certificate using a CA certificate and key
*/
static int issue()
bool pkcs10 = FALSE;
char *file = NULL, *dn = NULL, *hex = NULL, *cacert = NULL, *cakey = NULL;
char *error = NULL, *keyid = NULL;
- identification_t *id = NULL, *crl_issuer = NULL;;
+ identification_t *id = NULL;
linked_list_t *san, *cdps, *ocsp, *permitted, *excluded, *policies, *mappings;
int lifetime = 1095;
int pathlen = X509_NO_CONSTRAINT;
time_t not_before, not_after;
x509_flag_t flags = 0;
x509_t *x509;
+ x509_cdp_t *cdp = NULL;
x509_cert_policy_t *policy = NULL;
char *arg;
}
continue;
case 'u':
- cdps->insert_last(cdps, arg);
+ INIT(cdp,
+ .uri = strdup(arg),
+ );
+ cdps->insert_last(cdps, cdp);
continue;
case 'I':
- crl_issuer = identification_create_from_string(arg);
+ if (!cdp || cdp->issuer)
+ {
+ error = "--crlissuer must follow a --crl";
+ goto usage;
+ }
+ cdp->issuer = identification_create_from_string(arg);
continue;
case 'o':
ocsp->insert_last(ocsp, arg);
BUILD_NOT_AFTER_TIME, not_after, BUILD_SERIAL, serial,
BUILD_SUBJECT_ALTNAMES, san, BUILD_X509_FLAG, flags,
BUILD_PATHLEN, pathlen,
- BUILD_CRL_ISSUER, crl_issuer,
BUILD_CRL_DISTRIBUTION_POINTS, cdps,
BUILD_OCSP_ACCESS_LOCATIONS, ocsp,
BUILD_PERMITTED_NAME_CONSTRAINTS, permitted,
excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
policies->destroy_function(policies, (void*)destroy_cert_policy);
mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
- cdps->destroy(cdps);
+ cdps->destroy_function(cdps, (void*)destroy_cdp);
ocsp->destroy(ocsp);
- DESTROY_IF(crl_issuer);
free(encoding.ptr);
free(serial.ptr);
excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
policies->destroy_function(policies, (void*)destroy_cert_policy);
mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
- cdps->destroy(cdps);
+ cdps->destroy_function(cdps, (void*)destroy_cdp);
ocsp->destroy(ocsp);
- DESTROY_IF(crl_issuer);
return command_usage(error);
}
"issue a certificate using a CA certificate and key",
{"[--in file] [--type pub|pkcs10] --cakey file | --cakeyid hex",
" --cacert file --dn subject-dn [--san subjectAltName]+",
- "[--lifetime days] [--serial hex] [--crl uri]+ [--ocsp uri]+",
+ "[--lifetime days] [--serial hex] [--crl uri [--crlissuer i] ]+ [--ocsp uri]+",
"[--ca] [--pathlen len] [--flag serverAuth|clientAuth|crlSign|ocspSigning]+",
"[--nc-permitted name] [--nc-excluded name]",
"[--cert-policy oid [--cps-uri uri] [--user-notice text] ]+",
char *uri;
int len;
x509_flag_t flags;
+ x509_cdp_t *cdp;
x509_cert_policy_t *policy;
x509_policy_mapping_t *mapping;
first = TRUE;
enumerator = x509->create_crl_uri_enumerator(x509);
- while (enumerator->enumerate(enumerator, &uri, &id))
+ while (enumerator->enumerate(enumerator, &cdp))
{
if (first)
{
- printf("CRL URIs: %s", uri);
+ printf("CRL URIs: %s", cdp->uri);
first = FALSE;
}
else
{
- printf(" %s", uri);
+ printf(" %s", cdp->uri);
}
- if (id)
+ if (cdp->issuer)
{
- printf(" (CRL issuer: %Y)", id);
+ printf(" (CRL issuer: %Y)", cdp->issuer);
}
printf("\n");
}
x509crl_t *x509crl;
ca_info_t *ca;
enumerator_t *enumerator;
- char *point;
+ x509_cdp_t *cdp;
ca = get_ca_info(issuer, authKeyID);
}
enumerator = x509->create_crl_uri_enumerator(x509);
- while (enumerator->enumerate(enumerator, &point, NULL))
+ while (enumerator->enumerate(enumerator, &cdp))
{
- add_distribution_point(crluris, point);
+ add_distribution_point(crluris, cdp->uri);
}
enumerator->destroy(enumerator);
}
enumerator = x509->create_crl_uri_enumerator(x509);
- while (enumerator->enumerate(enumerator, &point, NULL))
+ while (enumerator->enumerate(enumerator, &cdp))
{
- add_distribution_point(x509crl->distributionPoints, point);
+ add_distribution_point(x509crl->distributionPoints, cdp->uri);
}
enumerator->destroy(enumerator);