Simplified format of x509 CRL URI parsing/enumerator
This commit is contained in:
@@ -41,7 +41,6 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
|
|||||||
"BUILD_CA_CERT",
|
"BUILD_CA_CERT",
|
||||||
"BUILD_CERT",
|
"BUILD_CERT",
|
||||||
"BUILD_CRL_DISTRIBUTION_POINTS",
|
"BUILD_CRL_DISTRIBUTION_POINTS",
|
||||||
"BUILD_CRL_ISSUER",
|
|
||||||
"BUILD_OCSP_ACCESS_LOCATIONS",
|
"BUILD_OCSP_ACCESS_LOCATIONS",
|
||||||
"BUILD_PATHLEN",
|
"BUILD_PATHLEN",
|
||||||
"BUILD_PERMITTED_NAME_CONSTRAINTS",
|
"BUILD_PERMITTED_NAME_CONSTRAINTS",
|
||||||
|
|||||||
@@ -87,10 +87,8 @@ enum builder_part_t {
|
|||||||
BUILD_CA_CERT,
|
BUILD_CA_CERT,
|
||||||
/** a certificate, certificate_t* */
|
/** a certificate, certificate_t* */
|
||||||
BUILD_CERT,
|
BUILD_CERT,
|
||||||
/** CRL distribution point URIs, linked_list_t* containing char* */
|
/** CRL distribution point URIs, x509_cdp_t* */
|
||||||
BUILD_CRL_DISTRIBUTION_POINTS,
|
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* */
|
/** OCSP AuthorityInfoAccess locations, linked_list_t* containing char* */
|
||||||
BUILD_OCSP_ACCESS_LOCATIONS,
|
BUILD_OCSP_ACCESS_LOCATIONS,
|
||||||
/** certificate path length constraint */
|
/** certificate path length constraint */
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
typedef struct x509_t x509_t;
|
typedef struct x509_t x509_t;
|
||||||
typedef struct x509_cert_policy_t x509_cert_policy_t;
|
typedef struct x509_cert_policy_t x509_cert_policy_t;
|
||||||
typedef struct x509_policy_mapping_t x509_policy_mapping_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;
|
typedef enum x509_flag_t x509_flag_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,6 +78,16 @@ struct x509_policy_mapping_t {
|
|||||||
chunk_t subject;
|
chunk_t subject;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X.509 CRL distributionPoint
|
||||||
|
*/
|
||||||
|
struct x509_cdp_t {
|
||||||
|
/** CDP URI, as string */
|
||||||
|
char *uri;
|
||||||
|
/** CRL issuer */
|
||||||
|
identification_t *issuer;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* X.509 certificate interface.
|
* X.509 certificate interface.
|
||||||
*
|
*
|
||||||
@@ -143,7 +154,7 @@ struct x509_t {
|
|||||||
/**
|
/**
|
||||||
* Create an enumerator over all CRL URIs and CRL Issuers.
|
* 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);
|
enumerator_t* (*create_crl_uri_enumerator)(x509_t *this);
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ struct private_openssl_x509_t {
|
|||||||
linked_list_t *issuerAltNames;
|
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;
|
linked_list_t *crl_uris;
|
||||||
|
|
||||||
@@ -152,33 +152,12 @@ struct private_openssl_x509_t {
|
|||||||
refcount_t ref;
|
refcount_t ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* 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);
|
DESTROY_IF(this->issuer);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@@ -289,36 +268,10 @@ METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
|
|||||||
return this->subjectAltNames->create_enumerator(this->subjectAltNames);
|
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*,
|
METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
|
||||||
private_openssl_x509_t *this)
|
private_openssl_x509_t *this)
|
||||||
{
|
{
|
||||||
return enumerator_create_nested(
|
return this->crl_uris->create_enumerator(this->crl_uris);
|
||||||
this->crl_uris->create_enumerator(this->crl_uris),
|
|
||||||
(void*)crl_enum_create, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
|
METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
|
||||||
@@ -660,9 +613,10 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
|
|||||||
{
|
{
|
||||||
CRL_DIST_POINTS *cdps;
|
CRL_DIST_POINTS *cdps;
|
||||||
DIST_POINT *cdp;
|
DIST_POINT *cdp;
|
||||||
identification_t *id;
|
identification_t *id, *issuer;
|
||||||
|
x509_cdp_t *entry;
|
||||||
char *uri;
|
char *uri;
|
||||||
int i, j, point_num, name_num;
|
int i, j, k, point_num, name_num, issuer_num;
|
||||||
|
|
||||||
cdps = X509V3_EXT_d2i(ext);
|
cdps = X509V3_EXT_d2i(ext);
|
||||||
if (!cdps)
|
if (!cdps)
|
||||||
@@ -675,11 +629,6 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
|
|||||||
cdp = sk_DIST_POINT_value(cdps, i);
|
cdp = sk_DIST_POINT_value(cdps, i);
|
||||||
if (cdp)
|
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 &&
|
if (cdp->distpoint && cdp->distpoint->type == 0 &&
|
||||||
cdp->distpoint->name.fullname)
|
cdp->distpoint->name.fullname)
|
||||||
{
|
{
|
||||||
@@ -692,25 +641,38 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
|
|||||||
{
|
{
|
||||||
if (asprintf(&uri, "%Y", id) > 0)
|
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);
|
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);
|
DIST_POINT_free(cdp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -486,13 +486,13 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer,
|
|||||||
auth_cfg_t *auth)
|
auth_cfg_t *auth)
|
||||||
{
|
{
|
||||||
cert_validation_t valid = VALIDATION_SKIPPED;
|
cert_validation_t valid = VALIDATION_SKIPPED;
|
||||||
identification_t *id;
|
|
||||||
certificate_t *best = NULL;
|
certificate_t *best = NULL;
|
||||||
|
identification_t *id;
|
||||||
|
x509_cdp_t *cdp;
|
||||||
bool uri_found = FALSE;
|
bool uri_found = FALSE;
|
||||||
certificate_t *current;
|
certificate_t *current;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
chunk_t chunk;
|
chunk_t chunk;
|
||||||
char *uri;
|
|
||||||
|
|
||||||
/* use issuers subjectKeyIdentifier to find a cached CRL / fetch from CDP */
|
/* use issuers subjectKeyIdentifier to find a cached CRL / fetch from CDP */
|
||||||
chunk = issuer->get_subjectKeyIdentifier(issuer);
|
chunk = issuer->get_subjectKeyIdentifier(issuer);
|
||||||
@@ -506,11 +506,11 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer,
|
|||||||
/* find a cached CRL or fetch via configured CDP via CRLIssuer */
|
/* find a cached CRL or fetch via configured CDP via CRLIssuer */
|
||||||
enumerator = subject->create_crl_uri_enumerator(subject);
|
enumerator = subject->create_crl_uri_enumerator(subject);
|
||||||
while (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED &&
|
while (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED &&
|
||||||
enumerator->enumerate(enumerator, &uri, &id))
|
enumerator->enumerate(enumerator, &cdp))
|
||||||
{
|
{
|
||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
valid = find_crl(subject, id, auth, &best, &uri_found);
|
valid = find_crl(subject, cdp->issuer, auth, &best, &uri_found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
@@ -519,17 +519,17 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer,
|
|||||||
if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
|
if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
|
||||||
{
|
{
|
||||||
enumerator = subject->create_crl_uri_enumerator(subject);
|
enumerator = subject->create_crl_uri_enumerator(subject);
|
||||||
while (enumerator->enumerate(enumerator, &uri, &id))
|
while (enumerator->enumerate(enumerator, &cdp))
|
||||||
{
|
{
|
||||||
uri_found = TRUE;
|
uri_found = TRUE;
|
||||||
current = fetch_crl(uri);
|
current = fetch_crl(cdp->uri);
|
||||||
if (current)
|
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 "
|
DBG1(DBG_CFG, "issuer of fetched CRL '%Y' does not match "
|
||||||
"certificates CRL issuer '%Y'",
|
"certificates CRL issuer '%Y'",
|
||||||
current->get_issuer(current), id);
|
current->get_issuer(current), cdp->issuer);
|
||||||
current->destroy(current);
|
current->destroy(current);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ struct private_x509_cert_t {
|
|||||||
linked_list_t *subjectAltNames;
|
linked_list_t *subjectAltNames;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of crlDistributionPoints as crl_uri_t
|
* List of crlDistributionPoints as x509_cdp_t*
|
||||||
*/
|
*/
|
||||||
linked_list_t *crl_uris;
|
linked_list_t *crl_uris;
|
||||||
|
|
||||||
@@ -217,33 +217,11 @@ static const chunk_t ASN1_subjectAltName_oid = chunk_from_chars(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRL URIs with associated issuer
|
* Destroy a CertificateDistributionPoint
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
static void crl_uri_destroy(x509_cdp_t *this)
|
||||||
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;
|
free(this->uri);
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
this->uris->destroy_function(this->uris, free);
|
|
||||||
DESTROY_IF(this->issuer);
|
DESTROY_IF(this->issuer);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
@@ -795,20 +773,64 @@ static const asn1Object_t crlDistributionPointsObjects[] = {
|
|||||||
#define CRL_DIST_POINTS_FULLNAME 3
|
#define CRL_DIST_POINTS_FULLNAME 3
|
||||||
#define CRL_DIST_POINTS_ISSUER 10
|
#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
|
* Extracts one or several crlDistributionPoints into a list
|
||||||
*/
|
*/
|
||||||
static void parse_crlDistributionPoints(chunk_t blob, int level0,
|
void x509_parse_crlDistributionPoints(chunk_t blob, int level0,
|
||||||
private_x509_cert_t *this)
|
linked_list_t *list)
|
||||||
{
|
{
|
||||||
|
linked_list_t *uris, *issuers;
|
||||||
asn1_parser_t *parser;
|
asn1_parser_t *parser;
|
||||||
chunk_t object;
|
chunk_t object;
|
||||||
int objectID;
|
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 = asn1_parser_create(crlDistributionPointsObjects, blob);
|
||||||
parser->set_top_level(parser, level0);
|
parser->set_top_level(parser, level0);
|
||||||
|
|
||||||
@@ -817,46 +839,26 @@ static void parse_crlDistributionPoints(chunk_t blob, int level0,
|
|||||||
switch (objectID)
|
switch (objectID)
|
||||||
{
|
{
|
||||||
case CRL_DIST_POINTS:
|
case CRL_DIST_POINTS:
|
||||||
entry = crl_uri_create(NULL);
|
add_cdps(list, uris, issuers);
|
||||||
this->crl_uris->insert_last(this->crl_uris, entry);
|
|
||||||
break;
|
break;
|
||||||
case CRL_DIST_POINTS_FULLNAME:
|
case CRL_DIST_POINTS_FULLNAME:
|
||||||
if (entry)
|
x509_parse_generalNames(object, parser->get_level(parser) + 1,
|
||||||
{
|
TRUE, uris);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case CRL_DIST_POINTS_ISSUER:
|
case CRL_DIST_POINTS_ISSUER:
|
||||||
if (entry)
|
x509_parse_generalNames(object, parser->get_level(parser) + 1,
|
||||||
{
|
TRUE, issuers);
|
||||||
x509_parse_generalNames(object, parser->get_level(parser)+1,
|
break;
|
||||||
TRUE, list);
|
default:
|
||||||
while (list->remove_last(list, (void**)&id) == SUCCESS)
|
|
||||||
{
|
|
||||||
if (!entry->issuer)
|
|
||||||
{
|
|
||||||
entry->issuer = id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id->destroy(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parser->destroy(parser);
|
parser->destroy(parser);
|
||||||
list->destroy(list);
|
|
||||||
|
add_cdps(list, uris, issuers);
|
||||||
|
|
||||||
|
uris->destroy(uris);
|
||||||
|
issuers->destroy(issuers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1391,7 +1393,8 @@ static bool parse_certificate(private_x509_cert_t *this)
|
|||||||
parse_basicConstraints(object, level, this);
|
parse_basicConstraints(object, level, this);
|
||||||
break;
|
break;
|
||||||
case OID_CRL_DISTRIBUTION_POINTS:
|
case OID_CRL_DISTRIBUTION_POINTS:
|
||||||
parse_crlDistributionPoints(object, level, this);
|
x509_parse_crlDistributionPoints(object, level,
|
||||||
|
this->crl_uris);
|
||||||
break;
|
break;
|
||||||
case OID_AUTHORITY_KEY_ID:
|
case OID_AUTHORITY_KEY_ID:
|
||||||
this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
|
this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
|
||||||
@@ -1741,36 +1744,10 @@ METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
|
|||||||
return this->ocsp_uris->create_enumerator(this->ocsp_uris);
|
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*,
|
METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
|
||||||
private_x509_cert_t *this)
|
private_x509_cert_t *this)
|
||||||
{
|
{
|
||||||
return enumerator_create_nested(
|
return this->crl_uris->create_enumerator(this->crl_uris);
|
||||||
this->crl_uris->create_enumerator(this->crl_uris),
|
|
||||||
(void*)crl_enum_create, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
|
METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
|
||||||
@@ -1968,11 +1945,11 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
|||||||
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
|
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
|
||||||
chunk_t policyConstraints = chunk_empty;
|
chunk_t policyConstraints = chunk_empty;
|
||||||
identification_t *issuer, *subject;
|
identification_t *issuer, *subject;
|
||||||
crl_uri_t *entry;
|
x509_cdp_t *cdp;
|
||||||
chunk_t key_info;
|
chunk_t key_info;
|
||||||
signature_scheme_t scheme;
|
signature_scheme_t scheme;
|
||||||
hasher_t *hasher;
|
hasher_t *hasher;
|
||||||
enumerator_t *enumerator, *uris;
|
enumerator_t *enumerator;
|
||||||
char *uri;
|
char *uri;
|
||||||
|
|
||||||
subject = cert->subject;
|
subject = cert->subject;
|
||||||
@@ -2023,28 +2000,21 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
|
|||||||
|
|
||||||
/* encode CRL distribution points extension */
|
/* encode CRL distribution points extension */
|
||||||
enumerator = cert->crl_uris->create_enumerator(cert->crl_uris);
|
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 distributionPoint, crlIssuer = chunk_empty;
|
||||||
chunk_t crlIssuer = chunk_empty, gns = chunk_empty;
|
|
||||||
|
|
||||||
if (entry->issuer)
|
if (cdp->issuer)
|
||||||
{
|
{
|
||||||
crlIssuer = asn1_wrap(ASN1_CONTEXT_C_2, "m",
|
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",
|
distributionPoint = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
asn1_wrap(ASN1_CONTEXT_C_0, "m",
|
asn1_wrap(ASN1_CONTEXT_C_0, "m",
|
||||||
asn1_wrap(ASN1_CONTEXT_C_0, "m", gns)),
|
asn1_wrap(ASN1_CONTEXT_C_0, "m",
|
||||||
crlIssuer);
|
asn1_wrap(ASN1_CONTEXT_S_6, "c",
|
||||||
|
chunk_create(cdp->uri, strlen(cdp->uri))))),
|
||||||
|
crlIssuer);
|
||||||
crlDistributionPoints = chunk_cat("mm", crlDistributionPoints,
|
crlDistributionPoints = chunk_cat("mm", crlDistributionPoints,
|
||||||
distributionPoint);
|
distributionPoint);
|
||||||
}
|
}
|
||||||
@@ -2385,7 +2355,6 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
|
|||||||
private_x509_cert_t *cert;
|
private_x509_cert_t *cert;
|
||||||
certificate_t *sign_cert = NULL;
|
certificate_t *sign_cert = NULL;
|
||||||
private_key_t *sign_key = NULL;
|
private_key_t *sign_key = NULL;
|
||||||
identification_t *crl_issuer = NULL;
|
|
||||||
hash_algorithm_t digest_alg = HASH_SHA1;
|
hash_algorithm_t digest_alg = HASH_SHA1;
|
||||||
|
|
||||||
cert = create_empty();
|
cert = create_empty();
|
||||||
@@ -2430,26 +2399,19 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
|
|||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
linked_list_t *list;
|
linked_list_t *list;
|
||||||
crl_uri_t *entry;
|
x509_cdp_t *in, *cdp;
|
||||||
char *uri;
|
|
||||||
|
|
||||||
list = va_arg(args, linked_list_t*);
|
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);
|
INIT(cdp,
|
||||||
enumerator = list->create_enumerator(list);
|
.uri = strdup(in->uri),
|
||||||
while (enumerator->enumerate(enumerator, &uri))
|
.issuer = in->issuer ? in->issuer->clone(in->issuer) : NULL,
|
||||||
{
|
);
|
||||||
entry->uris->insert_last(entry->uris, strdup(uri));
|
cert->crl_uris->insert_last(cert->crl_uris, cdp);
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
cert->crl_uris->insert_last(cert->crl_uris, entry);
|
|
||||||
}
|
}
|
||||||
continue;
|
enumerator->destroy(enumerator);
|
||||||
}
|
|
||||||
case BUILD_CRL_ISSUER:
|
|
||||||
{
|
|
||||||
crl_issuer = va_arg(args, identification_t*);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case BUILD_OCSP_ACCESS_LOCATIONS:
|
case BUILD_OCSP_ACCESS_LOCATIONS:
|
||||||
|
|||||||
@@ -43,6 +43,15 @@ static void destroy_policy_mapping(x509_policy_mapping_t *mapping)
|
|||||||
free(mapping);
|
free(mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Issue a certificate using a CA certificate and key
|
||||||
*/
|
*/
|
||||||
@@ -56,7 +65,7 @@ static int issue()
|
|||||||
bool pkcs10 = FALSE;
|
bool pkcs10 = FALSE;
|
||||||
char *file = NULL, *dn = NULL, *hex = NULL, *cacert = NULL, *cakey = NULL;
|
char *file = NULL, *dn = NULL, *hex = NULL, *cacert = NULL, *cakey = NULL;
|
||||||
char *error = NULL, *keyid = 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;
|
linked_list_t *san, *cdps, *ocsp, *permitted, *excluded, *policies, *mappings;
|
||||||
int lifetime = 1095;
|
int lifetime = 1095;
|
||||||
int pathlen = X509_NO_CONSTRAINT;
|
int pathlen = X509_NO_CONSTRAINT;
|
||||||
@@ -66,6 +75,7 @@ static int issue()
|
|||||||
time_t not_before, not_after;
|
time_t not_before, not_after;
|
||||||
x509_flag_t flags = 0;
|
x509_flag_t flags = 0;
|
||||||
x509_t *x509;
|
x509_t *x509;
|
||||||
|
x509_cdp_t *cdp = NULL;
|
||||||
x509_cert_policy_t *policy = NULL;
|
x509_cert_policy_t *policy = NULL;
|
||||||
char *arg;
|
char *arg;
|
||||||
|
|
||||||
@@ -233,10 +243,18 @@ static int issue()
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case 'u':
|
case 'u':
|
||||||
cdps->insert_last(cdps, arg);
|
INIT(cdp,
|
||||||
|
.uri = strdup(arg),
|
||||||
|
);
|
||||||
|
cdps->insert_last(cdps, cdp);
|
||||||
continue;
|
continue;
|
||||||
case 'I':
|
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;
|
continue;
|
||||||
case 'o':
|
case 'o':
|
||||||
ocsp->insert_last(ocsp, arg);
|
ocsp->insert_last(ocsp, arg);
|
||||||
@@ -420,7 +438,6 @@ static int issue()
|
|||||||
BUILD_NOT_AFTER_TIME, not_after, BUILD_SERIAL, serial,
|
BUILD_NOT_AFTER_TIME, not_after, BUILD_SERIAL, serial,
|
||||||
BUILD_SUBJECT_ALTNAMES, san, BUILD_X509_FLAG, flags,
|
BUILD_SUBJECT_ALTNAMES, san, BUILD_X509_FLAG, flags,
|
||||||
BUILD_PATHLEN, pathlen,
|
BUILD_PATHLEN, pathlen,
|
||||||
BUILD_CRL_ISSUER, crl_issuer,
|
|
||||||
BUILD_CRL_DISTRIBUTION_POINTS, cdps,
|
BUILD_CRL_DISTRIBUTION_POINTS, cdps,
|
||||||
BUILD_OCSP_ACCESS_LOCATIONS, ocsp,
|
BUILD_OCSP_ACCESS_LOCATIONS, ocsp,
|
||||||
BUILD_PERMITTED_NAME_CONSTRAINTS, permitted,
|
BUILD_PERMITTED_NAME_CONSTRAINTS, permitted,
|
||||||
@@ -458,9 +475,8 @@ end:
|
|||||||
excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
|
excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
|
||||||
policies->destroy_function(policies, (void*)destroy_cert_policy);
|
policies->destroy_function(policies, (void*)destroy_cert_policy);
|
||||||
mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
|
mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
|
||||||
cdps->destroy(cdps);
|
cdps->destroy_function(cdps, (void*)destroy_cdp);
|
||||||
ocsp->destroy(ocsp);
|
ocsp->destroy(ocsp);
|
||||||
DESTROY_IF(crl_issuer);
|
|
||||||
free(encoding.ptr);
|
free(encoding.ptr);
|
||||||
free(serial.ptr);
|
free(serial.ptr);
|
||||||
|
|
||||||
@@ -477,9 +493,8 @@ usage:
|
|||||||
excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
|
excluded->destroy_offset(excluded, offsetof(identification_t, destroy));
|
||||||
policies->destroy_function(policies, (void*)destroy_cert_policy);
|
policies->destroy_function(policies, (void*)destroy_cert_policy);
|
||||||
mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
|
mappings->destroy_function(mappings, (void*)destroy_policy_mapping);
|
||||||
cdps->destroy(cdps);
|
cdps->destroy_function(cdps, (void*)destroy_cdp);
|
||||||
ocsp->destroy(ocsp);
|
ocsp->destroy(ocsp);
|
||||||
DESTROY_IF(crl_issuer);
|
|
||||||
return command_usage(error);
|
return command_usage(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +508,7 @@ static void __attribute__ ((constructor))reg()
|
|||||||
"issue a certificate using a CA certificate and key",
|
"issue a certificate using a CA certificate and key",
|
||||||
{"[--in file] [--type pub|pkcs10] --cakey file | --cakeyid hex",
|
{"[--in file] [--type pub|pkcs10] --cakey file | --cakeyid hex",
|
||||||
" --cacert file --dn subject-dn [--san subjectAltName]+",
|
" --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]+",
|
"[--ca] [--pathlen len] [--flag serverAuth|clientAuth|crlSign|ocspSigning]+",
|
||||||
"[--nc-permitted name] [--nc-excluded name]",
|
"[--nc-permitted name] [--nc-excluded name]",
|
||||||
"[--cert-policy oid [--cps-uri uri] [--user-notice text] ]+",
|
"[--cert-policy oid [--cps-uri uri] [--user-notice text] ]+",
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ static void print_x509(x509_t *x509)
|
|||||||
char *uri;
|
char *uri;
|
||||||
int len;
|
int len;
|
||||||
x509_flag_t flags;
|
x509_flag_t flags;
|
||||||
|
x509_cdp_t *cdp;
|
||||||
x509_cert_policy_t *policy;
|
x509_cert_policy_t *policy;
|
||||||
x509_policy_mapping_t *mapping;
|
x509_policy_mapping_t *mapping;
|
||||||
|
|
||||||
@@ -140,20 +141,20 @@ static void print_x509(x509_t *x509)
|
|||||||
|
|
||||||
first = TRUE;
|
first = TRUE;
|
||||||
enumerator = x509->create_crl_uri_enumerator(x509);
|
enumerator = x509->create_crl_uri_enumerator(x509);
|
||||||
while (enumerator->enumerate(enumerator, &uri, &id))
|
while (enumerator->enumerate(enumerator, &cdp))
|
||||||
{
|
{
|
||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
printf("CRL URIs: %s", uri);
|
printf("CRL URIs: %s", cdp->uri);
|
||||||
first = FALSE;
|
first = FALSE;
|
||||||
}
|
}
|
||||||
else
|
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");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -352,7 +352,7 @@ cert_status_t verify_by_crl(cert_t *cert, time_t *until, time_t *revocationDate,
|
|||||||
x509crl_t *x509crl;
|
x509crl_t *x509crl;
|
||||||
ca_info_t *ca;
|
ca_info_t *ca;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
char *point;
|
x509_cdp_t *cdp;
|
||||||
|
|
||||||
ca = get_ca_info(issuer, authKeyID);
|
ca = get_ca_info(issuer, authKeyID);
|
||||||
|
|
||||||
@@ -376,9 +376,9 @@ cert_status_t verify_by_crl(cert_t *cert, time_t *until, time_t *revocationDate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
enumerator = x509->create_crl_uri_enumerator(x509);
|
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->destroy(enumerator);
|
||||||
|
|
||||||
@@ -416,9 +416,9 @@ cert_status_t verify_by_crl(cert_t *cert, time_t *until, time_t *revocationDate,
|
|||||||
}
|
}
|
||||||
|
|
||||||
enumerator = x509->create_crl_uri_enumerator(x509);
|
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);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user