* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
*/
static const X509V3_EXT_METHOD *standard_exts[] = {
-&v3_nscert,
-&v3_ns_ia5_list[0],
-&v3_ns_ia5_list[1],
-&v3_ns_ia5_list[2],
-&v3_ns_ia5_list[3],
-&v3_ns_ia5_list[4],
-&v3_ns_ia5_list[5],
-&v3_ns_ia5_list[6],
-&v3_skey_id,
-&v3_key_usage,
-&v3_pkey_usage_period,
-&v3_alt[0],
-&v3_alt[1],
-&v3_bcons,
-&v3_crl_num,
-&v3_cpols,
-&v3_akey_id,
-&v3_crld,
-&v3_ext_ku,
-&v3_delta_crl,
-&v3_crl_reason,
+ &v3_nscert,
+ &v3_ns_ia5_list[0],
+ &v3_ns_ia5_list[1],
+ &v3_ns_ia5_list[2],
+ &v3_ns_ia5_list[3],
+ &v3_ns_ia5_list[4],
+ &v3_ns_ia5_list[5],
+ &v3_ns_ia5_list[6],
+ &v3_skey_id,
+ &v3_key_usage,
+ &v3_pkey_usage_period,
+ &v3_alt[0],
+ &v3_alt[1],
+ &v3_bcons,
+ &v3_crl_num,
+ &v3_cpols,
+ &v3_akey_id,
+ &v3_crld,
+ &v3_ext_ku,
+ &v3_delta_crl,
+ &v3_crl_reason,
#ifndef OPENSSL_NO_OCSP
-&v3_crl_invdate,
+ &v3_crl_invdate,
#endif
-&v3_sxnet,
-&v3_info,
+ &v3_sxnet,
+ &v3_info,
#ifndef OPENSSL_NO_RFC3779
-&v3_addr,
-&v3_asid,
+ &v3_addr,
+ &v3_asid,
#endif
#ifndef OPENSSL_NO_OCSP
-&v3_ocsp_nonce,
-&v3_ocsp_crlid,
-&v3_ocsp_accresp,
-&v3_ocsp_nocheck,
-&v3_ocsp_acutoff,
-&v3_ocsp_serviceloc,
+ &v3_ocsp_nonce,
+ &v3_ocsp_crlid,
+ &v3_ocsp_accresp,
+ &v3_ocsp_nocheck,
+ &v3_ocsp_acutoff,
+ &v3_ocsp_serviceloc,
#endif
-&v3_sinfo,
-&v3_policy_constraints,
+ &v3_sinfo,
+ &v3_policy_constraints,
#ifndef OPENSSL_NO_OCSP
-&v3_crl_hold,
+ &v3_crl_hold,
#endif
-&v3_pci,
-&v3_name_constraints,
-&v3_policy_mappings,
-&v3_inhibit_anyp,
-&v3_idp,
-&v3_alt[2],
-&v3_freshest_crl,
+ &v3_pci,
+ &v3_name_constraints,
+ &v3_policy_mappings,
+ &v3_inhibit_anyp,
+ &v3_idp,
+ &v3_alt[2],
+ &v3_freshest_crl,
};
/* Number of standard extensions */
-
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
-
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
#include "pcy_int.h"
static int policy_data_cmp(const X509_POLICY_DATA * const *a,
- const X509_POLICY_DATA * const *b);
+ const X509_POLICY_DATA * const *b);
static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
/* Set cache entry according to CertificatePolicies extension.
* Note: this destroys the passed CERTIFICATEPOLICIES structure.
*/
-static int policy_cache_create(X509 *x,
- CERTIFICATEPOLICIES *policies, int crit)
- {
+static int
+policy_cache_create(X509 *x, CERTIFICATEPOLICIES *policies, int crit)
+{
int i;
int ret = 0;
X509_POLICY_CACHE *cache = x->policy_cache;
X509_POLICY_DATA *data = NULL;
POLICYINFO *policy;
+
if (sk_POLICYINFO_num(policies) == 0)
goto bad_policy;
cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
if (!cache->data)
goto bad_policy;
- for (i = 0; i < sk_POLICYINFO_num(policies); i++)
- {
+ for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
policy = sk_POLICYINFO_value(policies, i);
data = policy_data_new(policy, NULL, crit);
if (!data)
/* Duplicate policy OIDs are illegal: reject if matches
* found.
*/
- if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
- {
- if (cache->anyPolicy)
- {
+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+ if (cache->anyPolicy) {
ret = -1;
goto bad_policy;
- }
- cache->anyPolicy = data;
}
- else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1)
- {
+ cache->anyPolicy = data;
+ } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) {
ret = -1;
goto bad_policy;
- }
- else if (!sk_X509_POLICY_DATA_push(cache->data, data))
+ } else if (!sk_X509_POLICY_DATA_push(cache->data, data))
goto bad_policy;
data = NULL;
- }
+ }
ret = 1;
- bad_policy:
+
+bad_policy:
if (ret == -1)
x->ex_flags |= EXFLAG_INVALID_POLICY;
if (data)
policy_data_free(data);
sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
- if (ret <= 0)
- {
+ if (ret <= 0) {
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
cache->data = NULL;
- }
- return ret;
}
+ return ret;
+}
-
-static int policy_cache_new(X509 *x)
- {
+static int
+policy_cache_new(X509 *x)
+{
X509_POLICY_CACHE *cache;
ASN1_INTEGER *ext_any = NULL;
POLICY_CONSTRAINTS *ext_pcons = NULL;
CERTIFICATEPOLICIES *ext_cpols = NULL;
POLICY_MAPPINGS *ext_pmaps = NULL;
int i;
+
cache = malloc(sizeof(X509_POLICY_CACHE));
if (!cache)
return 0;
*/
ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
- if (!ext_pcons)
- {
+ if (!ext_pcons) {
if (i != -1)
goto bad_cache;
- }
- else
- {
- if (!ext_pcons->requireExplicitPolicy
- && !ext_pcons->inhibitPolicyMapping)
+ } else {
+ if (!ext_pcons->requireExplicitPolicy &&
+ !ext_pcons->inhibitPolicyMapping)
goto bad_cache;
if (!policy_cache_set_int(&cache->explicit_skip,
- ext_pcons->requireExplicitPolicy))
+ ext_pcons->requireExplicitPolicy))
goto bad_cache;
if (!policy_cache_set_int(&cache->map_skip,
- ext_pcons->inhibitPolicyMapping))
+ ext_pcons->inhibitPolicyMapping))
goto bad_cache;
- }
+ }
/* Process CertificatePolicies */
* there is no point continuing because the valid policies will be
* NULL.
*/
- if (!ext_cpols)
- {
+ if (!ext_cpols) {
/* If not absent some problem with extension */
if (i != -1)
goto bad_cache;
return 1;
- }
+ }
i = policy_cache_create(x, ext_cpols, i);
ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
- if (!ext_pmaps)
- {
+ if (!ext_pmaps) {
/* If not absent some problem with extension */
if (i != -1)
goto bad_cache;
- }
- else
- {
+ } else {
i = policy_cache_set_mapping(x, ext_pmaps);
if (i <= 0)
goto bad_cache;
- }
+ }
ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
- if (!ext_any)
- {
+ if (!ext_any) {
if (i != -1)
goto bad_cache;
- }
- else if (!policy_cache_set_int(&cache->any_skip, ext_any))
- goto bad_cache;
+ } else if (!policy_cache_set_int(&cache->any_skip, ext_any))
+ goto bad_cache;
- if (0)
- {
- bad_cache:
+ if (0) {
+bad_cache:
x->ex_flags |= EXFLAG_INVALID_POLICY;
- }
+ }
- if(ext_pcons)
+ if (ext_pcons)
POLICY_CONSTRAINTS_free(ext_pcons);
if (ext_any)
ASN1_INTEGER_free(ext_any);
return 1;
-
-
}
-void policy_cache_free(X509_POLICY_CACHE *cache)
- {
+void
+policy_cache_free(X509_POLICY_CACHE *cache)
+{
if (!cache)
return;
if (cache->anyPolicy)
if (cache->data)
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
free(cache);
- }
-
-const X509_POLICY_CACHE *policy_cache_set(X509 *x)
- {
+}
- if (x->policy_cache == NULL)
- {
+const X509_POLICY_CACHE *
+policy_cache_set(X509 *x)
+{
+ if (x->policy_cache == NULL) {
CRYPTO_w_lock(CRYPTO_LOCK_X509);
- policy_cache_new(x);
+ policy_cache_new(x);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
- }
+ }
return x->policy_cache;
+}
- }
-
-X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id)
- {
+X509_POLICY_DATA *
+policy_cache_find_data(const X509_POLICY_CACHE *cache, const ASN1_OBJECT *id)
+{
int idx;
X509_POLICY_DATA tmp;
+
tmp.valid_policy = (ASN1_OBJECT *)id;
idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
if (idx == -1)
return NULL;
return sk_X509_POLICY_DATA_value(cache->data, idx);
- }
+}
-static int policy_data_cmp(const X509_POLICY_DATA * const *a,
- const X509_POLICY_DATA * const *b)
- {
+static int
+policy_data_cmp(const X509_POLICY_DATA * const *a,
+ const X509_POLICY_DATA * const *b)
+{
return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
- }
+}
-static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
- {
+static int
+policy_cache_set_int(long *out, ASN1_INTEGER *value)
+{
if (value == NULL)
return 1;
if (value->type == V_ASN1_NEG_INTEGER)
return 0;
*out = ASN1_INTEGER_get(value);
return 1;
- }
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
/* Policy Node routines */
-void policy_data_free(X509_POLICY_DATA *data)
- {
+void
+policy_data_free(X509_POLICY_DATA *data)
+{
ASN1_OBJECT_free(data->valid_policy);
/* Don't free qualifiers if shared */
if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
sk_POLICYQUALINFO_pop_free(data->qualifier_set,
- POLICYQUALINFO_free);
+ POLICYQUALINFO_free);
sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
free(data);
- }
+}
/* Create a data based on an existing policy. If 'id' is NULL use the
* oid in the policy, otherwise use 'id'. This behaviour covers the two
* another source.
*/
-X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
- const ASN1_OBJECT *cid, int crit)
- {
+X509_POLICY_DATA *
+policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *cid, int crit)
+{
X509_POLICY_DATA *ret;
ASN1_OBJECT *id;
+
if (!policy && !cid)
return NULL;
- if (cid)
- {
+ if (cid) {
id = OBJ_dup(cid);
if (!id)
return NULL;
- }
- else
+ } else
id = NULL;
ret = malloc(sizeof(X509_POLICY_DATA));
if (!ret)
return NULL;
ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
- if (!ret->expected_policy_set)
- {
+ if (!ret->expected_policy_set) {
free(ret);
if (id)
ASN1_OBJECT_free(id);
return NULL;
- }
+ }
if (crit)
ret->flags = POLICY_DATA_FLAG_CRITICAL;
if (id)
ret->valid_policy = id;
- else
- {
+ else {
ret->valid_policy = policy->policyid;
policy->policyid = NULL;
- }
+ }
- if (policy)
- {
+ if (policy) {
ret->qualifier_set = policy->qualifiers;
policy->qualifiers = NULL;
- }
- else
+ } else
ret->qualifier_set = NULL;
return ret;
- }
-
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* can be kept static and cached with the certificate.
*/
-struct X509_POLICY_DATA_st
- {
+struct X509_POLICY_DATA_st {
unsigned int flags;
/* Policy OID and qualifiers for this data */
ASN1_OBJECT *valid_policy;
STACK_OF(POLICYQUALINFO) *qualifier_set;
STACK_OF(ASN1_OBJECT) *expected_policy_set;
- };
+};
/* X509_POLICY_DATA flags values */
/* This flag indicates the structure has been mapped using a policy mapping
- * extension. If policy mapping is not active its references get deleted.
+ * extension. If policy mapping is not active its references get deleted.
*/
#define POLICY_DATA_FLAG_MAPPED 0x1
* value or -1 if absent.
*/
long map_skip;
- };
+};
/*#define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL*/
/* This structure represents the relationship between nodes */
-struct X509_POLICY_NODE_st
- {
+struct X509_POLICY_NODE_st {
/* node data this refers to */
const X509_POLICY_DATA *data;
/* Parent node */
X509_POLICY_NODE *parent;
/* Number of child nodes */
int nchild;
- };
+};
-struct X509_POLICY_LEVEL_st
- {
+struct X509_POLICY_LEVEL_st {
/* Cert for this level */
X509 *cert;
/* nodes at this level */
/* Extra data */
/*STACK_OF(X509_POLICY_DATA) *extra_data;*/
unsigned int flags;
- };
+};
-struct X509_POLICY_TREE_st
- {
+struct X509_POLICY_TREE_st {
/* This is the tree 'level' data */
X509_POLICY_LEVEL *levels;
int nlevel;
STACK_OF(X509_POLICY_NODE) *auth_policies;
STACK_OF(X509_POLICY_NODE) *user_policies;
unsigned int flags;
- };
+};
/* Set if anyPolicy present in user policies */
#define POLICY_FLAG_ANY_POLICY 0x2
/* Internal functions */
X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
- int crit);
+ int crit);
void policy_data_free(X509_POLICY_DATA *data);
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id);
+ const ASN1_OBJECT *id);
int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
void policy_cache_free(X509_POLICY_CACHE *cache);
X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
- const X509_POLICY_NODE *parent,
- const ASN1_OBJECT *id);
+ const X509_POLICY_NODE *parent, const ASN1_OBJECT *id);
X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
- const ASN1_OBJECT *id);
+ const ASN1_OBJECT *id);
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
- const X509_POLICY_DATA *data,
- X509_POLICY_NODE *parent,
- X509_POLICY_TREE *tree);
+ const X509_POLICY_DATA *data, X509_POLICY_NODE *parent,
+ X509_POLICY_TREE *tree);
void policy_node_free(X509_POLICY_NODE *node);
int policy_node_match(const X509_POLICY_LEVEL *lvl,
- const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
+ const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
const X509_POLICY_CACHE *policy_cache_set(X509 *x);
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
/* X509_POLICY_TREE stuff */
-int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
- {
+int
+X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
+{
if (!tree)
return 0;
return tree->nlevel;
- }
+}
X509_POLICY_LEVEL *
- X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
- {
+X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
+{
if (!tree || (i < 0) || (i >= tree->nlevel))
return NULL;
return tree->levels + i;
- }
+}
STACK_OF(X509_POLICY_NODE) *
- X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
- {
+X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
+{
if (!tree)
return NULL;
return tree->auth_policies;
- }
+}
STACK_OF(X509_POLICY_NODE) *
- X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
- {
+X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
+{
if (!tree)
return NULL;
if (tree->flags & POLICY_FLAG_ANY_POLICY)
return tree->auth_policies;
else
return tree->user_policies;
- }
+}
/* X509_POLICY_LEVEL stuff */
-int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
- {
+int
+X509_policy_level_node_count(X509_POLICY_LEVEL *level)
+{
int n;
if (!level)
return 0;
if (level->nodes)
n += sk_X509_POLICY_NODE_num(level->nodes);
return n;
- }
+}
-X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
- {
+X509_POLICY_NODE *
+X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
+{
if (!level)
return NULL;
- if (level->anyPolicy)
- {
+ if (level->anyPolicy) {
if (i == 0)
return level->anyPolicy;
i--;
- }
- return sk_X509_POLICY_NODE_value(level->nodes, i);
}
+ return sk_X509_POLICY_NODE_value(level->nodes, i);
+}
/* X509_POLICY_NODE stuff */
-const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
- {
+const ASN1_OBJECT *
+X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
+{
if (!node)
return NULL;
return node->data->valid_policy;
- }
+}
#if 0
-int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
- {
+int
+X509_policy_node_get_critical(const X509_POLICY_NODE *node)
+{
if (node_critical(node))
return 1;
return 0;
- }
+}
#endif
STACK_OF(POLICYQUALINFO) *
- X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
- {
+X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
+{
if (!node)
return NULL;
return node->data->qualifier_set;
- }
+}
const X509_POLICY_NODE *
- X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
- {
+X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
+{
if (!node)
return NULL;
return node->parent;
- }
-
-
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* Note: this modifies the passed POLICY_MAPPINGS structure
*/
-int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
- {
+int
+policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
+{
POLICY_MAPPING *map;
X509_POLICY_DATA *data;
X509_POLICY_CACHE *cache = x->policy_cache;
int i;
int ret = 0;
- if (sk_POLICY_MAPPING_num(maps) == 0)
- {
+
+ if (sk_POLICY_MAPPING_num(maps) == 0) {
ret = -1;
goto bad_mapping;
- }
- for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
- {
+ }
+ for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) {
map = sk_POLICY_MAPPING_value(maps, i);
/* Reject if map to or from anyPolicy */
- if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
- || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy))
- {
+ if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) ||
+ (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) {
ret = -1;
goto bad_mapping;
- }
+ }
/* Attempt to find matching policy data */
data = policy_cache_find_data(cache, map->issuerDomainPolicy);
continue;
/* Create a NODE from anyPolicy */
- if (!data)
- {
+ if (!data) {
data = policy_data_new(NULL, map->issuerDomainPolicy,
- cache->anyPolicy->flags
- & POLICY_DATA_FLAG_CRITICAL);
+ cache->anyPolicy->flags &
+ POLICY_DATA_FLAG_CRITICAL);
if (!data)
goto bad_mapping;
data->qualifier_set = cache->anyPolicy->qualifier_set;
/*map->issuerDomainPolicy = NULL;*/
data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!sk_X509_POLICY_DATA_push(cache->data, data))
- {
+ if (!sk_X509_POLICY_DATA_push(cache->data, data)) {
policy_data_free(data);
goto bad_mapping;
- }
}
- else
+ } else
data->flags |= POLICY_DATA_FLAG_MAPPED;
- if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
- map->subjectDomainPolicy))
+ if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
+ map->subjectDomainPolicy))
goto bad_mapping;
map->subjectDomainPolicy = NULL;
-
- }
+ }
ret = 1;
- bad_mapping:
+
+bad_mapping:
if (ret == -1)
x->ex_flags |= EXFLAG_INVALID_POLICY;
sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
return ret;
-
- }
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
#include "pcy_int.h"
-static int node_cmp(const X509_POLICY_NODE * const *a,
- const X509_POLICY_NODE * const *b)
- {
+static int
+node_cmp(const X509_POLICY_NODE * const *a, const X509_POLICY_NODE * const *b)
+{
return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
- }
+}
STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
- {
+{
return sk_X509_POLICY_NODE_new(node_cmp);
- }
+}
-X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
- const ASN1_OBJECT *id)
- {
+X509_POLICY_NODE *
+tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, const ASN1_OBJECT *id)
+{
X509_POLICY_DATA n;
X509_POLICY_NODE l;
int idx;
return NULL;
return sk_X509_POLICY_NODE_value(nodes, idx);
+}
- }
-
-X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
- const X509_POLICY_NODE *parent,
- const ASN1_OBJECT *id)
- {
+X509_POLICY_NODE *
+level_find_node(const X509_POLICY_LEVEL *level, const X509_POLICY_NODE *parent,
+ const ASN1_OBJECT *id)
+{
X509_POLICY_NODE *node;
int i;
- for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
- {
+
+ for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
node = sk_X509_POLICY_NODE_value(level->nodes, i);
- if (node->parent == parent)
- {
+ if (node->parent == parent) {
if (!OBJ_cmp(node->data->valid_policy, id))
return node;
- }
}
- return NULL;
}
+ return NULL;
+}
-X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
- const X509_POLICY_DATA *data,
- X509_POLICY_NODE *parent,
- X509_POLICY_TREE *tree)
- {
+X509_POLICY_NODE *
+level_add_node(X509_POLICY_LEVEL *level, const X509_POLICY_DATA *data,
+ X509_POLICY_NODE *parent, X509_POLICY_TREE *tree)
+{
X509_POLICY_NODE *node;
+
node = malloc(sizeof(X509_POLICY_NODE));
if (!node)
return NULL;
node->data = data;
node->parent = parent;
node->nchild = 0;
- if (level)
- {
- if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
- {
+ if (level) {
+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
if (level->anyPolicy)
goto node_error;
level->anyPolicy = node;
- }
- else
- {
+ } else {
if (!level->nodes)
level->nodes = policy_node_cmp_new();
goto node_error;
if (!sk_X509_POLICY_NODE_push(level->nodes, node))
goto node_error;
- }
}
+ }
- if (tree)
- {
+ if (tree) {
if (!tree->extra_data)
- tree->extra_data = sk_X509_POLICY_DATA_new_null();
+ tree->extra_data = sk_X509_POLICY_DATA_new_null();
if (!tree->extra_data)
goto node_error;
if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
goto node_error;
- }
+ }
if (parent)
parent->nchild++;
return node;
- node_error:
+node_error:
policy_node_free(node);
return 0;
+}
- }
-
-void policy_node_free(X509_POLICY_NODE *node)
- {
+void
+policy_node_free(X509_POLICY_NODE *node)
+{
free(node);
- }
+}
/* See if a policy node matches a policy OID. If mapping enabled look through
* expected policy set otherwise just valid policy.
*/
-int policy_node_match(const X509_POLICY_LEVEL *lvl,
- const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
- {
+int
+policy_node_match(const X509_POLICY_LEVEL *lvl, const X509_POLICY_NODE *node,
+ const ASN1_OBJECT *oid)
+{
int i;
ASN1_OBJECT *policy_oid;
const X509_POLICY_DATA *x = node->data;
- if ( (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
- {
+ if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) ||
+ !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) {
if (!OBJ_cmp(x->valid_policy, oid))
return 1;
return 0;
- }
+ }
- for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) {
policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
if (!OBJ_cmp(policy_oid, oid))
return 1;
- }
- return 0;
-
}
+ return 0;
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
#ifdef OPENSSL_POLICY_DEBUG
-static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
- X509_POLICY_NODE *node, int indent)
- {
- if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
+static void
+expected_print(BIO *err, X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node,
+ int indent)
+{
+ if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) ||
+ !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
BIO_puts(err, " Not Mapped\n");
- else
- {
+ else {
int i;
STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
ASN1_OBJECT *oid;
BIO_puts(err, " Expected: ");
- for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
oid = sk_ASN1_OBJECT_value(pset, i);
if (i)
BIO_puts(err, ", ");
i2a_ASN1_OBJECT(err, oid);
- }
- BIO_puts(err, "\n");
}
+ BIO_puts(err, "\n");
}
+}
-static void tree_print(char *str, X509_POLICY_TREE *tree,
- X509_POLICY_LEVEL *curr)
- {
+static void
+tree_print(char *str, X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
+{
X509_POLICY_LEVEL *plev;
X509_POLICY_NODE *node;
int i;
BIO *err;
+
err = BIO_new_fp(stderr, BIO_NOCLOSE);
if (!curr)
curr = tree->levels + tree->nlevel;
curr++;
BIO_printf(err, "Level print after %s\n", str);
BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
- for (plev = tree->levels; plev != curr; plev++)
- {
+ for (plev = tree->levels; plev != curr; plev++) {
BIO_printf(err, "Level %ld, flags = %x\n",
- plev - tree->levels, plev->flags);
- for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
- {
+ plev - tree->levels, plev->flags);
+ for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
node = sk_X509_POLICY_NODE_value(plev->nodes, i);
X509_POLICY_NODE_print(err, node, 2);
expected_print(err, plev, node, 2);
BIO_printf(err, " Flags: %x\n", node->data->flags);
- }
+ }
if (plev->anyPolicy)
X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
- }
+ }
BIO_free(err);
-
- }
+}
#else
#define tree_print(a,b,c) /* */
* 6 Tree empty and requireExplicitPolicy true.
*/
-static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
- unsigned int flags)
- {
+static int
+tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, unsigned int flags)
+{
X509_POLICY_TREE *tree;
X509_POLICY_LEVEL *level;
const X509_POLICY_CACHE *cache;
int explicit_policy;
int any_skip;
int map_skip;
+
*ptree = NULL;
n = sk_X509_num(certs);
* trust anchor. Note any bad cache results on the way. Also can
* calculate explicit_policy value at this point.
*/
- for (i = n - 2; i >= 0; i--)
- {
+ for (i = n - 2; i >= 0; i--) {
x = sk_X509_value(certs, i);
X509_check_purpose(x, -1, -1);
cache = policy_cache_set(x);
*/
else if ((ret == 1) && !cache->data)
ret = 2;
- if (explicit_policy > 0)
- {
+ if (explicit_policy > 0) {
if (!(x->ex_flags & EXFLAG_SI))
explicit_policy--;
- if ((cache->explicit_skip != -1)
- && (cache->explicit_skip < explicit_policy))
+ if ((cache->explicit_skip != -1) &&
+ (cache->explicit_skip < explicit_policy))
explicit_policy = cache->explicit_skip;
- }
}
+ }
- if (ret != 1)
- {
+ if (ret != 1) {
if (ret == 2 && !explicit_policy)
return 6;
return ret;
- }
+ }
/* If we get this far initialize the tree */
tree->auth_policies = NULL;
tree->user_policies = NULL;
- if (!tree->levels)
- {
+ if (!tree->levels) {
free(tree);
return 0;
- }
+ }
memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
if (!data || !level_add_node(level, data, NULL, tree))
goto bad_tree;
- for (i = n - 2; i >= 0; i--)
- {
+ for (i = n - 2; i >= 0; i--) {
level++;
x = sk_X509_value(certs, i);
cache = policy_cache_set(x);
level->cert = x;
if (!cache->anyPolicy)
- level->flags |= X509_V_FLAG_INHIBIT_ANY;
+ level->flags |= X509_V_FLAG_INHIBIT_ANY;
/* Determine inhibit any and inhibit map flags */
- if (any_skip == 0)
- {
+ if (any_skip == 0) {
/* Any matching allowed if certificate is self
* issued and not the last in the chain.
*/
if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
level->flags |= X509_V_FLAG_INHIBIT_ANY;
- }
- else
- {
+ } else {
if (!(x->ex_flags & EXFLAG_SI))
any_skip--;
- if ((cache->any_skip >= 0)
- && (cache->any_skip < any_skip))
+ if ((cache->any_skip >= 0) &&
+ (cache->any_skip < any_skip))
any_skip = cache->any_skip;
- }
+ }
if (map_skip == 0)
level->flags |= X509_V_FLAG_INHIBIT_MAP;
- else
- {
+ else {
if (!(x->ex_flags & EXFLAG_SI))
map_skip--;
- if ((cache->map_skip >= 0)
- && (cache->map_skip < map_skip))
+ if ((cache->map_skip >= 0) &&
+ (cache->map_skip < map_skip))
map_skip = cache->map_skip;
- }
-
}
+ }
+
*ptree = tree;
if (explicit_policy)
else
return 5;
- bad_tree:
-
+bad_tree:
X509_policy_tree_free(tree);
return 0;
+}
- }
-
-static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
- const X509_POLICY_DATA *data)
- {
+static int
+tree_link_matching_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_DATA *data)
+{
X509_POLICY_LEVEL *last = curr - 1;
X509_POLICY_NODE *node;
int i, matched = 0;
+
/* Iterate through all in nodes linking matches */
- for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
- {
+ for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
node = sk_X509_POLICY_NODE_value(last->nodes, i);
- if (policy_node_match(last, node, data->valid_policy))
- {
+ if (policy_node_match(last, node, data->valid_policy)) {
if (!level_add_node(curr, data, node, NULL))
return 0;
matched = 1;
- }
}
- if (!matched && last->anyPolicy)
- {
+ }
+ if (!matched && last->anyPolicy) {
if (!level_add_node(curr, data, last->anyPolicy, NULL))
return 0;
- }
- return 1;
}
+ return 1;
+}
/* This corresponds to RFC3280 6.1.3(d)(1):
* link any data from CertificatePolicies onto matching parent
* or anyPolicy if no match.
*/
-static int tree_link_nodes(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache)
- {
+static int
+tree_link_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache)
+{
int i;
X509_POLICY_DATA *data;
- for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
- {
+ for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
data = sk_X509_POLICY_DATA_value(cache->data, i);
/* If a node is mapped any it doesn't have a corresponding
- * CertificatePolicies entry.
+ * CertificatePolicies entry.
* However such an identical node would be created
* if anyPolicy matching is enabled because there would be
* no match with the parent valid_policy_set. So we create
* right and we can prune it later.
*/
#if 0
- if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
- && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
+ if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) &&
+ !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
continue;
#endif
/* Look for matching nodes in previous level */
if (!tree_link_matching_nodes(curr, data))
- return 0;
- }
- return 1;
+ return 0;
}
+ return 1;
+}
/* This corresponds to RFC3280 6.1.3(d)(2):
* Create new data for any unmatched policies in the parent and link
* to anyPolicy.
*/
-static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id,
- X509_POLICY_NODE *node,
- X509_POLICY_TREE *tree)
- {
+static int
+tree_add_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
+ const ASN1_OBJECT *id, X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
X509_POLICY_DATA *data;
+
if (id == NULL)
id = node->data->valid_policy;
/* Create a new node with qualifiers from anyPolicy and
/* Curr may not have anyPolicy */
data->qualifier_set = cache->anyPolicy->qualifier_set;
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!level_add_node(curr, data, node, tree))
- {
+ if (!level_add_node(curr, data, node, tree)) {
policy_data_free(data);
return 0;
- }
+ }
return 1;
- }
+}
-static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- X509_POLICY_NODE *node,
- X509_POLICY_TREE *tree)
- {
+static int
+tree_link_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
+ X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
const X509_POLICY_LEVEL *last = curr - 1;
int i;
- if ( (last->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
- {
+ if ((last->flags & X509_V_FLAG_INHIBIT_MAP) ||
+ !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
/* If no policy mapping: matched if one child present */
if (node->nchild)
return 1;
if (!tree_add_unmatched(curr, cache, NULL, node, tree))
return 0;
/* Add it */
- }
- else
- {
+ } else {
/* If mapping: matched if one child per expected policy set */
STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
if (node->nchild == sk_ASN1_OBJECT_num(expset))
return 1;
/* Locate unmatched nodes */
- for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
if (level_find_node(curr, node, oid))
continue;
if (!tree_add_unmatched(curr, cache, oid, node, tree))
return 0;
- }
-
}
+ }
return 1;
+}
- }
-
-static int tree_link_any(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- X509_POLICY_TREE *tree)
- {
+static int
+tree_link_any(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
+ X509_POLICY_TREE *tree)
+{
int i;
/*X509_POLICY_DATA *data;*/
X509_POLICY_NODE *node;
X509_POLICY_LEVEL *last = curr - 1;
- for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
- {
+ for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
node = sk_X509_POLICY_NODE_value(last->nodes, i);
if (!tree_link_unmatched(curr, cache, node, tree))
* nodes.
*
* Note: need something better for policy mapping
- * because each node may have multiple children
+ * because each node may have multiple children
*/
if (node->nchild)
continue;
/* Create a new node with qualifiers from anyPolicy and
* id from unmatched node.
*/
- data = policy_data_new(NULL, node->data->valid_policy,
- node_critical(node));
+ data = policy_data_new(NULL, node->data->valid_policy,
+ node_critical(node));
if (data == NULL)
return 0;
/* Curr may not have anyPolicy */
data->qualifier_set = cache->anyPolicy->qualifier_set;
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!level_add_node(curr, data, node, tree))
- {
+ if (!level_add_node(curr, data, node, tree)) {
policy_data_free(data);
return 0;
- }
+ }
#endif
- }
+ }
/* Finally add link to anyPolicy */
- if (last->anyPolicy)
- {
+ if (last->anyPolicy) {
if (!level_add_node(curr, cache->anyPolicy,
- last->anyPolicy, NULL))
+ last->anyPolicy, NULL))
return 0;
- }
- return 1;
}
+ return 1;
+}
/* Prune the tree: delete any child mapped child data on the current level
* then proceed up the tree deleting any data with no children. If we ever
* have no data on a level we can halt because the tree will be empty.
*/
-static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
- {
+static int
+tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
+{
STACK_OF(X509_POLICY_NODE) *nodes;
X509_POLICY_NODE *node;
int i;
+
nodes = curr->nodes;
- if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
- {
- for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
- {
+ if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
node = sk_X509_POLICY_NODE_value(nodes, i);
/* Delete any mapped data: see RFC3280 XXXX */
- if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
- {
+ if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
node->parent->nchild--;
free(node);
- (void)sk_X509_POLICY_NODE_delete(nodes,i);
- }
+ (void)sk_X509_POLICY_NODE_delete(nodes, i);
}
}
+ }
- for(;;) {
+ for (;;) {
--curr;
nodes = curr->nodes;
- for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
- {
+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
node = sk_X509_POLICY_NODE_value(nodes, i);
- if (node->nchild == 0)
- {
+ if (node->nchild == 0) {
node->parent->nchild--;
free(node);
(void)sk_X509_POLICY_NODE_delete(nodes, i);
- }
}
- if (curr->anyPolicy && !curr->anyPolicy->nchild)
- {
+ }
+ if (curr->anyPolicy && !curr->anyPolicy->nchild) {
if (curr->anyPolicy->parent)
curr->anyPolicy->parent->nchild--;
free(curr->anyPolicy);
curr->anyPolicy = NULL;
- }
- if (curr == tree->levels)
- {
+ }
+ if (curr == tree->levels) {
/* If we zapped anyPolicy at top then tree is empty */
if (!curr->anyPolicy)
- return 2;
+ return 2;
return 1;
- }
}
+ }
return 1;
+}
- }
-
-static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
- X509_POLICY_NODE *pcy)
- {
- if (!*pnodes)
- {
+static int
+tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, X509_POLICY_NODE *pcy)
+{
+ if (!*pnodes) {
*pnodes = policy_node_cmp_new();
if (!*pnodes)
return 0;
- }
- else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
+ } else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
return 1;
if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
return 0;
return 1;
-
- }
+}
/* Calculate the authority set based on policy tree.
* The 'pnodes' parameter is used as a store for the set of policy nodes
* that pnodes should be freed.
*/
-static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
- STACK_OF(X509_POLICY_NODE) **pnodes)
- {
+static int
+tree_calculate_authority_set(X509_POLICY_TREE *tree,
+ STACK_OF(X509_POLICY_NODE) **pnodes)
+{
X509_POLICY_LEVEL *curr;
X509_POLICY_NODE *node, *anyptr;
STACK_OF(X509_POLICY_NODE) **addnodes;
int i, j;
+
curr = tree->levels + tree->nlevel - 1;
/* If last level contains anyPolicy set is anyPolicy */
- if (curr->anyPolicy)
- {
+ if (curr->anyPolicy) {
if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
return 0;
addnodes = pnodes;
- }
- else
+ } else
/* Add policies to authority set */
addnodes = &tree->auth_policies;
curr = tree->levels;
- for (i = 1; i < tree->nlevel; i++)
- {
+ for (i = 1; i < tree->nlevel; i++) {
/* If no anyPolicy node on this this level it can't
* appear on lower levels so end search.
*/
if (!(anyptr = curr->anyPolicy))
break;
curr++;
- for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
- {
+ for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
node = sk_X509_POLICY_NODE_value(curr->nodes, j);
- if ((node->parent == anyptr)
- && !tree_add_auth_node(addnodes, node))
- return 0;
- }
+ if ((node->parent == anyptr) &&
+ !tree_add_auth_node(addnodes, node))
+ return 0;
}
+ }
if (addnodes == pnodes)
return 2;
*pnodes = tree->auth_policies;
return 1;
- }
+}
-static int tree_calculate_user_set(X509_POLICY_TREE *tree,
- STACK_OF(ASN1_OBJECT) *policy_oids,
- STACK_OF(X509_POLICY_NODE) *auth_nodes)
- {
+static int
+tree_calculate_user_set(X509_POLICY_TREE *tree,
+ STACK_OF(ASN1_OBJECT) *policy_oids, STACK_OF(X509_POLICY_NODE) *auth_nodes)
+{
int i;
X509_POLICY_NODE *node;
ASN1_OBJECT *oid;
-
X509_POLICY_NODE *anyPolicy;
X509_POLICY_DATA *extra;
anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
- for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
oid = sk_ASN1_OBJECT_value(policy_oids, i);
- if (OBJ_obj2nid(oid) == NID_any_policy)
- {
+ if (OBJ_obj2nid(oid) == NID_any_policy) {
tree->flags |= POLICY_FLAG_ANY_POLICY;
return 1;
- }
}
+ }
- for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
oid = sk_ASN1_OBJECT_value(policy_oids, i);
node = tree_find_sk(auth_nodes, oid);
- if (!node)
- {
+ if (!node) {
if (!anyPolicy)
continue;
/* Create a new node with policy ID from user set
* and qualifiers from anyPolicy.
*/
extra = policy_data_new(NULL, oid,
- node_critical(anyPolicy));
+ node_critical(anyPolicy));
if (!extra)
return 0;
extra->qualifier_set = anyPolicy->data->qualifier_set;
- extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
- | POLICY_DATA_FLAG_EXTRA_NODE;
+ extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS |
+ POLICY_DATA_FLAG_EXTRA_NODE;
node = level_add_node(NULL, extra, anyPolicy->parent,
- tree);
- }
- if (!tree->user_policies)
- {
+ tree);
+ }
+ if (!tree->user_policies) {
tree->user_policies = sk_X509_POLICY_NODE_new_null();
if (!tree->user_policies)
return 1;
- }
+ }
if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
return 0;
- }
- return 1;
-
}
+ return 1;
+}
-static int tree_evaluate(X509_POLICY_TREE *tree)
- {
+static int
+tree_evaluate(X509_POLICY_TREE *tree)
+{
int ret, i;
X509_POLICY_LEVEL *curr = tree->levels + 1;
const X509_POLICY_CACHE *cache;
- for(i = 1; i < tree->nlevel; i++, curr++)
- {
+ for (i = 1; i < tree->nlevel; i++, curr++) {
cache = policy_cache_set(curr->cert);
if (!tree_link_nodes(curr, cache))
return 0;
- if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
- && !tree_link_any(curr, cache, tree))
+ if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) &&
+ !tree_link_any(curr, cache, tree))
return 0;
- tree_print("before tree_prune()", tree, curr);
+ tree_print("before tree_prune()", tree, curr);
ret = tree_prune(tree, curr);
if (ret != 1)
return ret;
- }
+ }
return 1;
+}
- }
-
-static void exnode_free(X509_POLICY_NODE *node)
- {
+static void
+exnode_free(X509_POLICY_NODE *node)
+{
if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
free(node);
- }
+}
-
-void X509_policy_tree_free(X509_POLICY_TREE *tree)
- {
+void
+X509_policy_tree_free(X509_POLICY_TREE *tree)
+{
X509_POLICY_LEVEL *curr;
int i;
sk_X509_POLICY_NODE_free(tree->auth_policies);
sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
- for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
- {
+ for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
if (curr->cert)
X509_free(curr->cert);
if (curr->nodes)
sk_X509_POLICY_NODE_pop_free(curr->nodes,
- policy_node_free);
+ policy_node_free);
if (curr->anyPolicy)
policy_node_free(curr->anyPolicy);
- }
+ }
if (tree->extra_data)
sk_X509_POLICY_DATA_pop_free(tree->extra_data,
- policy_data_free);
+ policy_data_free);
free(tree->levels);
free(tree);
-
- }
+}
/* Application policy checking function.
* Return codes:
* -2 User constrained policy set empty and requireExplicit true.
*/
-int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
- STACK_OF(X509) *certs,
- STACK_OF(ASN1_OBJECT) *policy_oids,
- unsigned int flags)
- {
+int
+X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+ STACK_OF(X509) *certs, STACK_OF(ASN1_OBJECT) *policy_oids,
+ unsigned int flags)
+{
int ret;
X509_POLICY_TREE *tree = NULL;
STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
- *ptree = NULL;
+ *ptree = NULL;
*pexplicit_policy = 0;
ret = tree_init(&tree, certs, flags);
- switch (ret)
- {
+ switch (ret) {
/* Tree empty requireExplicit False: OK */
- case 2:
+ case 2:
return 1;
/* Some internal error */
- case -1:
+ case -1:
return -1;
/* Some internal error */
- case 0:
+ case 0:
return 0;
/* Tree empty requireExplicit True: Error */
- case 6:
+ case 6:
*pexplicit_policy = 1;
return -2;
/* Tree OK requireExplicit True: OK and continue */
- case 5:
+ case 5:
*pexplicit_policy = 1;
break;
/* Tree OK: continue */
- case 1:
+ case 1:
if (!tree)
/*
* tree_init() returns success and a null tree
*/
return 1;
break;
- }
+ }
- if (!tree) goto error;
+ if (!tree)
+ goto error;
ret = tree_evaluate(tree);
tree_print("tree_evaluate()", tree, NULL);
goto error;
/* Return value 2 means tree empty */
- if (ret == 2)
- {
+ if (ret == 2) {
X509_policy_tree_free(tree);
if (*pexplicit_policy)
return -2;
else
return 1;
- }
+ }
/* Tree is not empty: continue */
if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
goto error;
-
+
if (ret == 2)
sk_X509_POLICY_NODE_free(auth_nodes);
if (tree)
*ptree = tree;
- if (*pexplicit_policy)
- {
+ if (*pexplicit_policy) {
nodes = X509_policy_tree_get0_user_policies(tree);
if (sk_X509_POLICY_NODE_num(nodes) <= 0)
return -2;
- }
+ }
return 1;
- error:
-
+error:
X509_policy_tree_free(tree);
return 0;
-
- }
-
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
*/
static const X509V3_EXT_METHOD *standard_exts[] = {
-&v3_nscert,
-&v3_ns_ia5_list[0],
-&v3_ns_ia5_list[1],
-&v3_ns_ia5_list[2],
-&v3_ns_ia5_list[3],
-&v3_ns_ia5_list[4],
-&v3_ns_ia5_list[5],
-&v3_ns_ia5_list[6],
-&v3_skey_id,
-&v3_key_usage,
-&v3_pkey_usage_period,
-&v3_alt[0],
-&v3_alt[1],
-&v3_bcons,
-&v3_crl_num,
-&v3_cpols,
-&v3_akey_id,
-&v3_crld,
-&v3_ext_ku,
-&v3_delta_crl,
-&v3_crl_reason,
+ &v3_nscert,
+ &v3_ns_ia5_list[0],
+ &v3_ns_ia5_list[1],
+ &v3_ns_ia5_list[2],
+ &v3_ns_ia5_list[3],
+ &v3_ns_ia5_list[4],
+ &v3_ns_ia5_list[5],
+ &v3_ns_ia5_list[6],
+ &v3_skey_id,
+ &v3_key_usage,
+ &v3_pkey_usage_period,
+ &v3_alt[0],
+ &v3_alt[1],
+ &v3_bcons,
+ &v3_crl_num,
+ &v3_cpols,
+ &v3_akey_id,
+ &v3_crld,
+ &v3_ext_ku,
+ &v3_delta_crl,
+ &v3_crl_reason,
#ifndef OPENSSL_NO_OCSP
-&v3_crl_invdate,
+ &v3_crl_invdate,
#endif
-&v3_sxnet,
-&v3_info,
+ &v3_sxnet,
+ &v3_info,
#ifndef OPENSSL_NO_RFC3779
-&v3_addr,
-&v3_asid,
+ &v3_addr,
+ &v3_asid,
#endif
#ifndef OPENSSL_NO_OCSP
-&v3_ocsp_nonce,
-&v3_ocsp_crlid,
-&v3_ocsp_accresp,
-&v3_ocsp_nocheck,
-&v3_ocsp_acutoff,
-&v3_ocsp_serviceloc,
+ &v3_ocsp_nonce,
+ &v3_ocsp_crlid,
+ &v3_ocsp_accresp,
+ &v3_ocsp_nocheck,
+ &v3_ocsp_acutoff,
+ &v3_ocsp_serviceloc,
#endif
-&v3_sinfo,
-&v3_policy_constraints,
+ &v3_sinfo,
+ &v3_policy_constraints,
#ifndef OPENSSL_NO_OCSP
-&v3_crl_hold,
+ &v3_crl_hold,
#endif
-&v3_pci,
-&v3_name_constraints,
-&v3_policy_mappings,
-&v3_inhibit_anyp,
-&v3_idp,
-&v3_alt[2],
-&v3_freshest_crl,
+ &v3_pci,
+ &v3_name_constraints,
+ &v3_policy_mappings,
+ &v3_inhibit_anyp,
+ &v3_idp,
+ &v3_alt[2],
+ &v3_freshest_crl,
};
/* Number of standard extensions */
-
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
-
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
#include "pcy_int.h"
static int policy_data_cmp(const X509_POLICY_DATA * const *a,
- const X509_POLICY_DATA * const *b);
+ const X509_POLICY_DATA * const *b);
static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
/* Set cache entry according to CertificatePolicies extension.
* Note: this destroys the passed CERTIFICATEPOLICIES structure.
*/
-static int policy_cache_create(X509 *x,
- CERTIFICATEPOLICIES *policies, int crit)
- {
+static int
+policy_cache_create(X509 *x, CERTIFICATEPOLICIES *policies, int crit)
+{
int i;
int ret = 0;
X509_POLICY_CACHE *cache = x->policy_cache;
X509_POLICY_DATA *data = NULL;
POLICYINFO *policy;
+
if (sk_POLICYINFO_num(policies) == 0)
goto bad_policy;
cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
if (!cache->data)
goto bad_policy;
- for (i = 0; i < sk_POLICYINFO_num(policies); i++)
- {
+ for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
policy = sk_POLICYINFO_value(policies, i);
data = policy_data_new(policy, NULL, crit);
if (!data)
/* Duplicate policy OIDs are illegal: reject if matches
* found.
*/
- if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
- {
- if (cache->anyPolicy)
- {
+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+ if (cache->anyPolicy) {
ret = -1;
goto bad_policy;
- }
- cache->anyPolicy = data;
}
- else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1)
- {
+ cache->anyPolicy = data;
+ } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) {
ret = -1;
goto bad_policy;
- }
- else if (!sk_X509_POLICY_DATA_push(cache->data, data))
+ } else if (!sk_X509_POLICY_DATA_push(cache->data, data))
goto bad_policy;
data = NULL;
- }
+ }
ret = 1;
- bad_policy:
+
+bad_policy:
if (ret == -1)
x->ex_flags |= EXFLAG_INVALID_POLICY;
if (data)
policy_data_free(data);
sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
- if (ret <= 0)
- {
+ if (ret <= 0) {
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
cache->data = NULL;
- }
- return ret;
}
+ return ret;
+}
-
-static int policy_cache_new(X509 *x)
- {
+static int
+policy_cache_new(X509 *x)
+{
X509_POLICY_CACHE *cache;
ASN1_INTEGER *ext_any = NULL;
POLICY_CONSTRAINTS *ext_pcons = NULL;
CERTIFICATEPOLICIES *ext_cpols = NULL;
POLICY_MAPPINGS *ext_pmaps = NULL;
int i;
+
cache = malloc(sizeof(X509_POLICY_CACHE));
if (!cache)
return 0;
*/
ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
- if (!ext_pcons)
- {
+ if (!ext_pcons) {
if (i != -1)
goto bad_cache;
- }
- else
- {
- if (!ext_pcons->requireExplicitPolicy
- && !ext_pcons->inhibitPolicyMapping)
+ } else {
+ if (!ext_pcons->requireExplicitPolicy &&
+ !ext_pcons->inhibitPolicyMapping)
goto bad_cache;
if (!policy_cache_set_int(&cache->explicit_skip,
- ext_pcons->requireExplicitPolicy))
+ ext_pcons->requireExplicitPolicy))
goto bad_cache;
if (!policy_cache_set_int(&cache->map_skip,
- ext_pcons->inhibitPolicyMapping))
+ ext_pcons->inhibitPolicyMapping))
goto bad_cache;
- }
+ }
/* Process CertificatePolicies */
* there is no point continuing because the valid policies will be
* NULL.
*/
- if (!ext_cpols)
- {
+ if (!ext_cpols) {
/* If not absent some problem with extension */
if (i != -1)
goto bad_cache;
return 1;
- }
+ }
i = policy_cache_create(x, ext_cpols, i);
ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
- if (!ext_pmaps)
- {
+ if (!ext_pmaps) {
/* If not absent some problem with extension */
if (i != -1)
goto bad_cache;
- }
- else
- {
+ } else {
i = policy_cache_set_mapping(x, ext_pmaps);
if (i <= 0)
goto bad_cache;
- }
+ }
ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
- if (!ext_any)
- {
+ if (!ext_any) {
if (i != -1)
goto bad_cache;
- }
- else if (!policy_cache_set_int(&cache->any_skip, ext_any))
- goto bad_cache;
+ } else if (!policy_cache_set_int(&cache->any_skip, ext_any))
+ goto bad_cache;
- if (0)
- {
- bad_cache:
+ if (0) {
+bad_cache:
x->ex_flags |= EXFLAG_INVALID_POLICY;
- }
+ }
- if(ext_pcons)
+ if (ext_pcons)
POLICY_CONSTRAINTS_free(ext_pcons);
if (ext_any)
ASN1_INTEGER_free(ext_any);
return 1;
-
-
}
-void policy_cache_free(X509_POLICY_CACHE *cache)
- {
+void
+policy_cache_free(X509_POLICY_CACHE *cache)
+{
if (!cache)
return;
if (cache->anyPolicy)
if (cache->data)
sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
free(cache);
- }
-
-const X509_POLICY_CACHE *policy_cache_set(X509 *x)
- {
+}
- if (x->policy_cache == NULL)
- {
+const X509_POLICY_CACHE *
+policy_cache_set(X509 *x)
+{
+ if (x->policy_cache == NULL) {
CRYPTO_w_lock(CRYPTO_LOCK_X509);
- policy_cache_new(x);
+ policy_cache_new(x);
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
- }
+ }
return x->policy_cache;
+}
- }
-
-X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id)
- {
+X509_POLICY_DATA *
+policy_cache_find_data(const X509_POLICY_CACHE *cache, const ASN1_OBJECT *id)
+{
int idx;
X509_POLICY_DATA tmp;
+
tmp.valid_policy = (ASN1_OBJECT *)id;
idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
if (idx == -1)
return NULL;
return sk_X509_POLICY_DATA_value(cache->data, idx);
- }
+}
-static int policy_data_cmp(const X509_POLICY_DATA * const *a,
- const X509_POLICY_DATA * const *b)
- {
+static int
+policy_data_cmp(const X509_POLICY_DATA * const *a,
+ const X509_POLICY_DATA * const *b)
+{
return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
- }
+}
-static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
- {
+static int
+policy_cache_set_int(long *out, ASN1_INTEGER *value)
+{
if (value == NULL)
return 1;
if (value->type == V_ASN1_NEG_INTEGER)
return 0;
*out = ASN1_INTEGER_get(value);
return 1;
- }
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
/* Policy Node routines */
-void policy_data_free(X509_POLICY_DATA *data)
- {
+void
+policy_data_free(X509_POLICY_DATA *data)
+{
ASN1_OBJECT_free(data->valid_policy);
/* Don't free qualifiers if shared */
if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
sk_POLICYQUALINFO_pop_free(data->qualifier_set,
- POLICYQUALINFO_free);
+ POLICYQUALINFO_free);
sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
free(data);
- }
+}
/* Create a data based on an existing policy. If 'id' is NULL use the
* oid in the policy, otherwise use 'id'. This behaviour covers the two
* another source.
*/
-X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
- const ASN1_OBJECT *cid, int crit)
- {
+X509_POLICY_DATA *
+policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *cid, int crit)
+{
X509_POLICY_DATA *ret;
ASN1_OBJECT *id;
+
if (!policy && !cid)
return NULL;
- if (cid)
- {
+ if (cid) {
id = OBJ_dup(cid);
if (!id)
return NULL;
- }
- else
+ } else
id = NULL;
ret = malloc(sizeof(X509_POLICY_DATA));
if (!ret)
return NULL;
ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
- if (!ret->expected_policy_set)
- {
+ if (!ret->expected_policy_set) {
free(ret);
if (id)
ASN1_OBJECT_free(id);
return NULL;
- }
+ }
if (crit)
ret->flags = POLICY_DATA_FLAG_CRITICAL;
if (id)
ret->valid_policy = id;
- else
- {
+ else {
ret->valid_policy = policy->policyid;
policy->policyid = NULL;
- }
+ }
- if (policy)
- {
+ if (policy) {
ret->qualifier_set = policy->qualifiers;
policy->qualifiers = NULL;
- }
- else
+ } else
ret->qualifier_set = NULL;
return ret;
- }
-
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* can be kept static and cached with the certificate.
*/
-struct X509_POLICY_DATA_st
- {
+struct X509_POLICY_DATA_st {
unsigned int flags;
/* Policy OID and qualifiers for this data */
ASN1_OBJECT *valid_policy;
STACK_OF(POLICYQUALINFO) *qualifier_set;
STACK_OF(ASN1_OBJECT) *expected_policy_set;
- };
+};
/* X509_POLICY_DATA flags values */
/* This flag indicates the structure has been mapped using a policy mapping
- * extension. If policy mapping is not active its references get deleted.
+ * extension. If policy mapping is not active its references get deleted.
*/
#define POLICY_DATA_FLAG_MAPPED 0x1
* value or -1 if absent.
*/
long map_skip;
- };
+};
/*#define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL*/
/* This structure represents the relationship between nodes */
-struct X509_POLICY_NODE_st
- {
+struct X509_POLICY_NODE_st {
/* node data this refers to */
const X509_POLICY_DATA *data;
/* Parent node */
X509_POLICY_NODE *parent;
/* Number of child nodes */
int nchild;
- };
+};
-struct X509_POLICY_LEVEL_st
- {
+struct X509_POLICY_LEVEL_st {
/* Cert for this level */
X509 *cert;
/* nodes at this level */
/* Extra data */
/*STACK_OF(X509_POLICY_DATA) *extra_data;*/
unsigned int flags;
- };
+};
-struct X509_POLICY_TREE_st
- {
+struct X509_POLICY_TREE_st {
/* This is the tree 'level' data */
X509_POLICY_LEVEL *levels;
int nlevel;
STACK_OF(X509_POLICY_NODE) *auth_policies;
STACK_OF(X509_POLICY_NODE) *user_policies;
unsigned int flags;
- };
+};
/* Set if anyPolicy present in user policies */
#define POLICY_FLAG_ANY_POLICY 0x2
/* Internal functions */
X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
- int crit);
+ int crit);
void policy_data_free(X509_POLICY_DATA *data);
X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id);
+ const ASN1_OBJECT *id);
int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
void policy_cache_free(X509_POLICY_CACHE *cache);
X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
- const X509_POLICY_NODE *parent,
- const ASN1_OBJECT *id);
+ const X509_POLICY_NODE *parent, const ASN1_OBJECT *id);
X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
- const ASN1_OBJECT *id);
+ const ASN1_OBJECT *id);
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
- const X509_POLICY_DATA *data,
- X509_POLICY_NODE *parent,
- X509_POLICY_TREE *tree);
+ const X509_POLICY_DATA *data, X509_POLICY_NODE *parent,
+ X509_POLICY_TREE *tree);
void policy_node_free(X509_POLICY_NODE *node);
int policy_node_match(const X509_POLICY_LEVEL *lvl,
- const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
+ const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
const X509_POLICY_CACHE *policy_cache_set(X509 *x);
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
/* X509_POLICY_TREE stuff */
-int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
- {
+int
+X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
+{
if (!tree)
return 0;
return tree->nlevel;
- }
+}
X509_POLICY_LEVEL *
- X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
- {
+X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i)
+{
if (!tree || (i < 0) || (i >= tree->nlevel))
return NULL;
return tree->levels + i;
- }
+}
STACK_OF(X509_POLICY_NODE) *
- X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
- {
+X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree)
+{
if (!tree)
return NULL;
return tree->auth_policies;
- }
+}
STACK_OF(X509_POLICY_NODE) *
- X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
- {
+X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree)
+{
if (!tree)
return NULL;
if (tree->flags & POLICY_FLAG_ANY_POLICY)
return tree->auth_policies;
else
return tree->user_policies;
- }
+}
/* X509_POLICY_LEVEL stuff */
-int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
- {
+int
+X509_policy_level_node_count(X509_POLICY_LEVEL *level)
+{
int n;
if (!level)
return 0;
if (level->nodes)
n += sk_X509_POLICY_NODE_num(level->nodes);
return n;
- }
+}
-X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
- {
+X509_POLICY_NODE *
+X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
+{
if (!level)
return NULL;
- if (level->anyPolicy)
- {
+ if (level->anyPolicy) {
if (i == 0)
return level->anyPolicy;
i--;
- }
- return sk_X509_POLICY_NODE_value(level->nodes, i);
}
+ return sk_X509_POLICY_NODE_value(level->nodes, i);
+}
/* X509_POLICY_NODE stuff */
-const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
- {
+const ASN1_OBJECT *
+X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
+{
if (!node)
return NULL;
return node->data->valid_policy;
- }
+}
#if 0
-int X509_policy_node_get_critical(const X509_POLICY_NODE *node)
- {
+int
+X509_policy_node_get_critical(const X509_POLICY_NODE *node)
+{
if (node_critical(node))
return 1;
return 0;
- }
+}
#endif
STACK_OF(POLICYQUALINFO) *
- X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
- {
+X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node)
+{
if (!node)
return NULL;
return node->data->qualifier_set;
- }
+}
const X509_POLICY_NODE *
- X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
- {
+X509_policy_node_get0_parent(const X509_POLICY_NODE *node)
+{
if (!node)
return NULL;
return node->parent;
- }
-
-
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* Note: this modifies the passed POLICY_MAPPINGS structure
*/
-int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
- {
+int
+policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
+{
POLICY_MAPPING *map;
X509_POLICY_DATA *data;
X509_POLICY_CACHE *cache = x->policy_cache;
int i;
int ret = 0;
- if (sk_POLICY_MAPPING_num(maps) == 0)
- {
+
+ if (sk_POLICY_MAPPING_num(maps) == 0) {
ret = -1;
goto bad_mapping;
- }
- for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++)
- {
+ }
+ for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) {
map = sk_POLICY_MAPPING_value(maps, i);
/* Reject if map to or from anyPolicy */
- if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
- || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy))
- {
+ if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) ||
+ (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) {
ret = -1;
goto bad_mapping;
- }
+ }
/* Attempt to find matching policy data */
data = policy_cache_find_data(cache, map->issuerDomainPolicy);
continue;
/* Create a NODE from anyPolicy */
- if (!data)
- {
+ if (!data) {
data = policy_data_new(NULL, map->issuerDomainPolicy,
- cache->anyPolicy->flags
- & POLICY_DATA_FLAG_CRITICAL);
+ cache->anyPolicy->flags &
+ POLICY_DATA_FLAG_CRITICAL);
if (!data)
goto bad_mapping;
data->qualifier_set = cache->anyPolicy->qualifier_set;
/*map->issuerDomainPolicy = NULL;*/
data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!sk_X509_POLICY_DATA_push(cache->data, data))
- {
+ if (!sk_X509_POLICY_DATA_push(cache->data, data)) {
policy_data_free(data);
goto bad_mapping;
- }
}
- else
+ } else
data->flags |= POLICY_DATA_FLAG_MAPPED;
- if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
- map->subjectDomainPolicy))
+ if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
+ map->subjectDomainPolicy))
goto bad_mapping;
map->subjectDomainPolicy = NULL;
-
- }
+ }
ret = 1;
- bad_mapping:
+
+bad_mapping:
if (ret == -1)
x->ex_flags |= EXFLAG_INVALID_POLICY;
sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
return ret;
-
- }
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
#include "pcy_int.h"
-static int node_cmp(const X509_POLICY_NODE * const *a,
- const X509_POLICY_NODE * const *b)
- {
+static int
+node_cmp(const X509_POLICY_NODE * const *a, const X509_POLICY_NODE * const *b)
+{
return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
- }
+}
STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
- {
+{
return sk_X509_POLICY_NODE_new(node_cmp);
- }
+}
-X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
- const ASN1_OBJECT *id)
- {
+X509_POLICY_NODE *
+tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, const ASN1_OBJECT *id)
+{
X509_POLICY_DATA n;
X509_POLICY_NODE l;
int idx;
return NULL;
return sk_X509_POLICY_NODE_value(nodes, idx);
+}
- }
-
-X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
- const X509_POLICY_NODE *parent,
- const ASN1_OBJECT *id)
- {
+X509_POLICY_NODE *
+level_find_node(const X509_POLICY_LEVEL *level, const X509_POLICY_NODE *parent,
+ const ASN1_OBJECT *id)
+{
X509_POLICY_NODE *node;
int i;
- for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
- {
+
+ for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
node = sk_X509_POLICY_NODE_value(level->nodes, i);
- if (node->parent == parent)
- {
+ if (node->parent == parent) {
if (!OBJ_cmp(node->data->valid_policy, id))
return node;
- }
}
- return NULL;
}
+ return NULL;
+}
-X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
- const X509_POLICY_DATA *data,
- X509_POLICY_NODE *parent,
- X509_POLICY_TREE *tree)
- {
+X509_POLICY_NODE *
+level_add_node(X509_POLICY_LEVEL *level, const X509_POLICY_DATA *data,
+ X509_POLICY_NODE *parent, X509_POLICY_TREE *tree)
+{
X509_POLICY_NODE *node;
+
node = malloc(sizeof(X509_POLICY_NODE));
if (!node)
return NULL;
node->data = data;
node->parent = parent;
node->nchild = 0;
- if (level)
- {
- if (OBJ_obj2nid(data->valid_policy) == NID_any_policy)
- {
+ if (level) {
+ if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
if (level->anyPolicy)
goto node_error;
level->anyPolicy = node;
- }
- else
- {
+ } else {
if (!level->nodes)
level->nodes = policy_node_cmp_new();
goto node_error;
if (!sk_X509_POLICY_NODE_push(level->nodes, node))
goto node_error;
- }
}
+ }
- if (tree)
- {
+ if (tree) {
if (!tree->extra_data)
- tree->extra_data = sk_X509_POLICY_DATA_new_null();
+ tree->extra_data = sk_X509_POLICY_DATA_new_null();
if (!tree->extra_data)
goto node_error;
if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
goto node_error;
- }
+ }
if (parent)
parent->nchild++;
return node;
- node_error:
+node_error:
policy_node_free(node);
return 0;
+}
- }
-
-void policy_node_free(X509_POLICY_NODE *node)
- {
+void
+policy_node_free(X509_POLICY_NODE *node)
+{
free(node);
- }
+}
/* See if a policy node matches a policy OID. If mapping enabled look through
* expected policy set otherwise just valid policy.
*/
-int policy_node_match(const X509_POLICY_LEVEL *lvl,
- const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
- {
+int
+policy_node_match(const X509_POLICY_LEVEL *lvl, const X509_POLICY_NODE *node,
+ const ASN1_OBJECT *oid)
+{
int i;
ASN1_OBJECT *policy_oid;
const X509_POLICY_DATA *x = node->data;
- if ( (lvl->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(x->flags & POLICY_DATA_FLAG_MAP_MASK))
- {
+ if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) ||
+ !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) {
if (!OBJ_cmp(x->valid_policy, oid))
return 1;
return 0;
- }
+ }
- for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) {
policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
if (!OBJ_cmp(policy_oid, oid))
return 1;
- }
- return 0;
-
}
+ return 0;
+}
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
#ifdef OPENSSL_POLICY_DEBUG
-static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
- X509_POLICY_NODE *node, int indent)
- {
- if ( (lev->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
+static void
+expected_print(BIO *err, X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node,
+ int indent)
+{
+ if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) ||
+ !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
BIO_puts(err, " Not Mapped\n");
- else
- {
+ else {
int i;
STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
ASN1_OBJECT *oid;
BIO_puts(err, " Expected: ");
- for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
oid = sk_ASN1_OBJECT_value(pset, i);
if (i)
BIO_puts(err, ", ");
i2a_ASN1_OBJECT(err, oid);
- }
- BIO_puts(err, "\n");
}
+ BIO_puts(err, "\n");
}
+}
-static void tree_print(char *str, X509_POLICY_TREE *tree,
- X509_POLICY_LEVEL *curr)
- {
+static void
+tree_print(char *str, X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
+{
X509_POLICY_LEVEL *plev;
X509_POLICY_NODE *node;
int i;
BIO *err;
+
err = BIO_new_fp(stderr, BIO_NOCLOSE);
if (!curr)
curr = tree->levels + tree->nlevel;
curr++;
BIO_printf(err, "Level print after %s\n", str);
BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
- for (plev = tree->levels; plev != curr; plev++)
- {
+ for (plev = tree->levels; plev != curr; plev++) {
BIO_printf(err, "Level %ld, flags = %x\n",
- plev - tree->levels, plev->flags);
- for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++)
- {
+ plev - tree->levels, plev->flags);
+ for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
node = sk_X509_POLICY_NODE_value(plev->nodes, i);
X509_POLICY_NODE_print(err, node, 2);
expected_print(err, plev, node, 2);
BIO_printf(err, " Flags: %x\n", node->data->flags);
- }
+ }
if (plev->anyPolicy)
X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
- }
+ }
BIO_free(err);
-
- }
+}
#else
#define tree_print(a,b,c) /* */
* 6 Tree empty and requireExplicitPolicy true.
*/
-static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
- unsigned int flags)
- {
+static int
+tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, unsigned int flags)
+{
X509_POLICY_TREE *tree;
X509_POLICY_LEVEL *level;
const X509_POLICY_CACHE *cache;
int explicit_policy;
int any_skip;
int map_skip;
+
*ptree = NULL;
n = sk_X509_num(certs);
* trust anchor. Note any bad cache results on the way. Also can
* calculate explicit_policy value at this point.
*/
- for (i = n - 2; i >= 0; i--)
- {
+ for (i = n - 2; i >= 0; i--) {
x = sk_X509_value(certs, i);
X509_check_purpose(x, -1, -1);
cache = policy_cache_set(x);
*/
else if ((ret == 1) && !cache->data)
ret = 2;
- if (explicit_policy > 0)
- {
+ if (explicit_policy > 0) {
if (!(x->ex_flags & EXFLAG_SI))
explicit_policy--;
- if ((cache->explicit_skip != -1)
- && (cache->explicit_skip < explicit_policy))
+ if ((cache->explicit_skip != -1) &&
+ (cache->explicit_skip < explicit_policy))
explicit_policy = cache->explicit_skip;
- }
}
+ }
- if (ret != 1)
- {
+ if (ret != 1) {
if (ret == 2 && !explicit_policy)
return 6;
return ret;
- }
+ }
/* If we get this far initialize the tree */
tree->auth_policies = NULL;
tree->user_policies = NULL;
- if (!tree->levels)
- {
+ if (!tree->levels) {
free(tree);
return 0;
- }
+ }
memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL));
if (!data || !level_add_node(level, data, NULL, tree))
goto bad_tree;
- for (i = n - 2; i >= 0; i--)
- {
+ for (i = n - 2; i >= 0; i--) {
level++;
x = sk_X509_value(certs, i);
cache = policy_cache_set(x);
level->cert = x;
if (!cache->anyPolicy)
- level->flags |= X509_V_FLAG_INHIBIT_ANY;
+ level->flags |= X509_V_FLAG_INHIBIT_ANY;
/* Determine inhibit any and inhibit map flags */
- if (any_skip == 0)
- {
+ if (any_skip == 0) {
/* Any matching allowed if certificate is self
* issued and not the last in the chain.
*/
if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
level->flags |= X509_V_FLAG_INHIBIT_ANY;
- }
- else
- {
+ } else {
if (!(x->ex_flags & EXFLAG_SI))
any_skip--;
- if ((cache->any_skip >= 0)
- && (cache->any_skip < any_skip))
+ if ((cache->any_skip >= 0) &&
+ (cache->any_skip < any_skip))
any_skip = cache->any_skip;
- }
+ }
if (map_skip == 0)
level->flags |= X509_V_FLAG_INHIBIT_MAP;
- else
- {
+ else {
if (!(x->ex_flags & EXFLAG_SI))
map_skip--;
- if ((cache->map_skip >= 0)
- && (cache->map_skip < map_skip))
+ if ((cache->map_skip >= 0) &&
+ (cache->map_skip < map_skip))
map_skip = cache->map_skip;
- }
-
}
+ }
+
*ptree = tree;
if (explicit_policy)
else
return 5;
- bad_tree:
-
+bad_tree:
X509_policy_tree_free(tree);
return 0;
+}
- }
-
-static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
- const X509_POLICY_DATA *data)
- {
+static int
+tree_link_matching_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_DATA *data)
+{
X509_POLICY_LEVEL *last = curr - 1;
X509_POLICY_NODE *node;
int i, matched = 0;
+
/* Iterate through all in nodes linking matches */
- for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
- {
+ for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
node = sk_X509_POLICY_NODE_value(last->nodes, i);
- if (policy_node_match(last, node, data->valid_policy))
- {
+ if (policy_node_match(last, node, data->valid_policy)) {
if (!level_add_node(curr, data, node, NULL))
return 0;
matched = 1;
- }
}
- if (!matched && last->anyPolicy)
- {
+ }
+ if (!matched && last->anyPolicy) {
if (!level_add_node(curr, data, last->anyPolicy, NULL))
return 0;
- }
- return 1;
}
+ return 1;
+}
/* This corresponds to RFC3280 6.1.3(d)(1):
* link any data from CertificatePolicies onto matching parent
* or anyPolicy if no match.
*/
-static int tree_link_nodes(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache)
- {
+static int
+tree_link_nodes(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache)
+{
int i;
X509_POLICY_DATA *data;
- for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++)
- {
+ for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
data = sk_X509_POLICY_DATA_value(cache->data, i);
/* If a node is mapped any it doesn't have a corresponding
- * CertificatePolicies entry.
+ * CertificatePolicies entry.
* However such an identical node would be created
* if anyPolicy matching is enabled because there would be
* no match with the parent valid_policy_set. So we create
* right and we can prune it later.
*/
#if 0
- if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY)
- && !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
+ if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) &&
+ !(curr->flags & X509_V_FLAG_INHIBIT_ANY))
continue;
#endif
/* Look for matching nodes in previous level */
if (!tree_link_matching_nodes(curr, data))
- return 0;
- }
- return 1;
+ return 0;
}
+ return 1;
+}
/* This corresponds to RFC3280 6.1.3(d)(2):
* Create new data for any unmatched policies in the parent and link
* to anyPolicy.
*/
-static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- const ASN1_OBJECT *id,
- X509_POLICY_NODE *node,
- X509_POLICY_TREE *tree)
- {
+static int
+tree_add_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
+ const ASN1_OBJECT *id, X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
X509_POLICY_DATA *data;
+
if (id == NULL)
id = node->data->valid_policy;
/* Create a new node with qualifiers from anyPolicy and
/* Curr may not have anyPolicy */
data->qualifier_set = cache->anyPolicy->qualifier_set;
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!level_add_node(curr, data, node, tree))
- {
+ if (!level_add_node(curr, data, node, tree)) {
policy_data_free(data);
return 0;
- }
+ }
return 1;
- }
+}
-static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- X509_POLICY_NODE *node,
- X509_POLICY_TREE *tree)
- {
+static int
+tree_link_unmatched(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
+ X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
const X509_POLICY_LEVEL *last = curr - 1;
int i;
- if ( (last->flags & X509_V_FLAG_INHIBIT_MAP)
- || !(node->data->flags & POLICY_DATA_FLAG_MAPPED))
- {
+ if ((last->flags & X509_V_FLAG_INHIBIT_MAP) ||
+ !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
/* If no policy mapping: matched if one child present */
if (node->nchild)
return 1;
if (!tree_add_unmatched(curr, cache, NULL, node, tree))
return 0;
/* Add it */
- }
- else
- {
+ } else {
/* If mapping: matched if one child per expected policy set */
STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
if (node->nchild == sk_ASN1_OBJECT_num(expset))
return 1;
/* Locate unmatched nodes */
- for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
if (level_find_node(curr, node, oid))
continue;
if (!tree_add_unmatched(curr, cache, oid, node, tree))
return 0;
- }
-
}
+ }
return 1;
+}
- }
-
-static int tree_link_any(X509_POLICY_LEVEL *curr,
- const X509_POLICY_CACHE *cache,
- X509_POLICY_TREE *tree)
- {
+static int
+tree_link_any(X509_POLICY_LEVEL *curr, const X509_POLICY_CACHE *cache,
+ X509_POLICY_TREE *tree)
+{
int i;
/*X509_POLICY_DATA *data;*/
X509_POLICY_NODE *node;
X509_POLICY_LEVEL *last = curr - 1;
- for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++)
- {
+ for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
node = sk_X509_POLICY_NODE_value(last->nodes, i);
if (!tree_link_unmatched(curr, cache, node, tree))
* nodes.
*
* Note: need something better for policy mapping
- * because each node may have multiple children
+ * because each node may have multiple children
*/
if (node->nchild)
continue;
/* Create a new node with qualifiers from anyPolicy and
* id from unmatched node.
*/
- data = policy_data_new(NULL, node->data->valid_policy,
- node_critical(node));
+ data = policy_data_new(NULL, node->data->valid_policy,
+ node_critical(node));
if (data == NULL)
return 0;
/* Curr may not have anyPolicy */
data->qualifier_set = cache->anyPolicy->qualifier_set;
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
- if (!level_add_node(curr, data, node, tree))
- {
+ if (!level_add_node(curr, data, node, tree)) {
policy_data_free(data);
return 0;
- }
+ }
#endif
- }
+ }
/* Finally add link to anyPolicy */
- if (last->anyPolicy)
- {
+ if (last->anyPolicy) {
if (!level_add_node(curr, cache->anyPolicy,
- last->anyPolicy, NULL))
+ last->anyPolicy, NULL))
return 0;
- }
- return 1;
}
+ return 1;
+}
/* Prune the tree: delete any child mapped child data on the current level
* then proceed up the tree deleting any data with no children. If we ever
* have no data on a level we can halt because the tree will be empty.
*/
-static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
- {
+static int
+tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
+{
STACK_OF(X509_POLICY_NODE) *nodes;
X509_POLICY_NODE *node;
int i;
+
nodes = curr->nodes;
- if (curr->flags & X509_V_FLAG_INHIBIT_MAP)
- {
- for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
- {
+ if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
node = sk_X509_POLICY_NODE_value(nodes, i);
/* Delete any mapped data: see RFC3280 XXXX */
- if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK)
- {
+ if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
node->parent->nchild--;
free(node);
- (void)sk_X509_POLICY_NODE_delete(nodes,i);
- }
+ (void)sk_X509_POLICY_NODE_delete(nodes, i);
}
}
+ }
- for(;;) {
+ for (;;) {
--curr;
nodes = curr->nodes;
- for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--)
- {
+ for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
node = sk_X509_POLICY_NODE_value(nodes, i);
- if (node->nchild == 0)
- {
+ if (node->nchild == 0) {
node->parent->nchild--;
free(node);
(void)sk_X509_POLICY_NODE_delete(nodes, i);
- }
}
- if (curr->anyPolicy && !curr->anyPolicy->nchild)
- {
+ }
+ if (curr->anyPolicy && !curr->anyPolicy->nchild) {
if (curr->anyPolicy->parent)
curr->anyPolicy->parent->nchild--;
free(curr->anyPolicy);
curr->anyPolicy = NULL;
- }
- if (curr == tree->levels)
- {
+ }
+ if (curr == tree->levels) {
/* If we zapped anyPolicy at top then tree is empty */
if (!curr->anyPolicy)
- return 2;
+ return 2;
return 1;
- }
}
+ }
return 1;
+}
- }
-
-static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
- X509_POLICY_NODE *pcy)
- {
- if (!*pnodes)
- {
+static int
+tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, X509_POLICY_NODE *pcy)
+{
+ if (!*pnodes) {
*pnodes = policy_node_cmp_new();
if (!*pnodes)
return 0;
- }
- else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
+ } else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
return 1;
if (!sk_X509_POLICY_NODE_push(*pnodes, pcy))
return 0;
return 1;
-
- }
+}
/* Calculate the authority set based on policy tree.
* The 'pnodes' parameter is used as a store for the set of policy nodes
* that pnodes should be freed.
*/
-static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
- STACK_OF(X509_POLICY_NODE) **pnodes)
- {
+static int
+tree_calculate_authority_set(X509_POLICY_TREE *tree,
+ STACK_OF(X509_POLICY_NODE) **pnodes)
+{
X509_POLICY_LEVEL *curr;
X509_POLICY_NODE *node, *anyptr;
STACK_OF(X509_POLICY_NODE) **addnodes;
int i, j;
+
curr = tree->levels + tree->nlevel - 1;
/* If last level contains anyPolicy set is anyPolicy */
- if (curr->anyPolicy)
- {
+ if (curr->anyPolicy) {
if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
return 0;
addnodes = pnodes;
- }
- else
+ } else
/* Add policies to authority set */
addnodes = &tree->auth_policies;
curr = tree->levels;
- for (i = 1; i < tree->nlevel; i++)
- {
+ for (i = 1; i < tree->nlevel; i++) {
/* If no anyPolicy node on this this level it can't
* appear on lower levels so end search.
*/
if (!(anyptr = curr->anyPolicy))
break;
curr++;
- for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++)
- {
+ for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
node = sk_X509_POLICY_NODE_value(curr->nodes, j);
- if ((node->parent == anyptr)
- && !tree_add_auth_node(addnodes, node))
- return 0;
- }
+ if ((node->parent == anyptr) &&
+ !tree_add_auth_node(addnodes, node))
+ return 0;
}
+ }
if (addnodes == pnodes)
return 2;
*pnodes = tree->auth_policies;
return 1;
- }
+}
-static int tree_calculate_user_set(X509_POLICY_TREE *tree,
- STACK_OF(ASN1_OBJECT) *policy_oids,
- STACK_OF(X509_POLICY_NODE) *auth_nodes)
- {
+static int
+tree_calculate_user_set(X509_POLICY_TREE *tree,
+ STACK_OF(ASN1_OBJECT) *policy_oids, STACK_OF(X509_POLICY_NODE) *auth_nodes)
+{
int i;
X509_POLICY_NODE *node;
ASN1_OBJECT *oid;
-
X509_POLICY_NODE *anyPolicy;
X509_POLICY_DATA *extra;
anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
- for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
oid = sk_ASN1_OBJECT_value(policy_oids, i);
- if (OBJ_obj2nid(oid) == NID_any_policy)
- {
+ if (OBJ_obj2nid(oid) == NID_any_policy) {
tree->flags |= POLICY_FLAG_ANY_POLICY;
return 1;
- }
}
+ }
- for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++)
- {
+ for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
oid = sk_ASN1_OBJECT_value(policy_oids, i);
node = tree_find_sk(auth_nodes, oid);
- if (!node)
- {
+ if (!node) {
if (!anyPolicy)
continue;
/* Create a new node with policy ID from user set
* and qualifiers from anyPolicy.
*/
extra = policy_data_new(NULL, oid,
- node_critical(anyPolicy));
+ node_critical(anyPolicy));
if (!extra)
return 0;
extra->qualifier_set = anyPolicy->data->qualifier_set;
- extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
- | POLICY_DATA_FLAG_EXTRA_NODE;
+ extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS |
+ POLICY_DATA_FLAG_EXTRA_NODE;
node = level_add_node(NULL, extra, anyPolicy->parent,
- tree);
- }
- if (!tree->user_policies)
- {
+ tree);
+ }
+ if (!tree->user_policies) {
tree->user_policies = sk_X509_POLICY_NODE_new_null();
if (!tree->user_policies)
return 1;
- }
+ }
if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
return 0;
- }
- return 1;
-
}
+ return 1;
+}
-static int tree_evaluate(X509_POLICY_TREE *tree)
- {
+static int
+tree_evaluate(X509_POLICY_TREE *tree)
+{
int ret, i;
X509_POLICY_LEVEL *curr = tree->levels + 1;
const X509_POLICY_CACHE *cache;
- for(i = 1; i < tree->nlevel; i++, curr++)
- {
+ for (i = 1; i < tree->nlevel; i++, curr++) {
cache = policy_cache_set(curr->cert);
if (!tree_link_nodes(curr, cache))
return 0;
- if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
- && !tree_link_any(curr, cache, tree))
+ if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) &&
+ !tree_link_any(curr, cache, tree))
return 0;
- tree_print("before tree_prune()", tree, curr);
+ tree_print("before tree_prune()", tree, curr);
ret = tree_prune(tree, curr);
if (ret != 1)
return ret;
- }
+ }
return 1;
+}
- }
-
-static void exnode_free(X509_POLICY_NODE *node)
- {
+static void
+exnode_free(X509_POLICY_NODE *node)
+{
if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
free(node);
- }
+}
-
-void X509_policy_tree_free(X509_POLICY_TREE *tree)
- {
+void
+X509_policy_tree_free(X509_POLICY_TREE *tree)
+{
X509_POLICY_LEVEL *curr;
int i;
sk_X509_POLICY_NODE_free(tree->auth_policies);
sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
- for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++)
- {
+ for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
if (curr->cert)
X509_free(curr->cert);
if (curr->nodes)
sk_X509_POLICY_NODE_pop_free(curr->nodes,
- policy_node_free);
+ policy_node_free);
if (curr->anyPolicy)
policy_node_free(curr->anyPolicy);
- }
+ }
if (tree->extra_data)
sk_X509_POLICY_DATA_pop_free(tree->extra_data,
- policy_data_free);
+ policy_data_free);
free(tree->levels);
free(tree);
-
- }
+}
/* Application policy checking function.
* Return codes:
* -2 User constrained policy set empty and requireExplicit true.
*/
-int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
- STACK_OF(X509) *certs,
- STACK_OF(ASN1_OBJECT) *policy_oids,
- unsigned int flags)
- {
+int
+X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+ STACK_OF(X509) *certs, STACK_OF(ASN1_OBJECT) *policy_oids,
+ unsigned int flags)
+{
int ret;
X509_POLICY_TREE *tree = NULL;
STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
- *ptree = NULL;
+ *ptree = NULL;
*pexplicit_policy = 0;
ret = tree_init(&tree, certs, flags);
- switch (ret)
- {
+ switch (ret) {
/* Tree empty requireExplicit False: OK */
- case 2:
+ case 2:
return 1;
/* Some internal error */
- case -1:
+ case -1:
return -1;
/* Some internal error */
- case 0:
+ case 0:
return 0;
/* Tree empty requireExplicit True: Error */
- case 6:
+ case 6:
*pexplicit_policy = 1;
return -2;
/* Tree OK requireExplicit True: OK and continue */
- case 5:
+ case 5:
*pexplicit_policy = 1;
break;
/* Tree OK: continue */
- case 1:
+ case 1:
if (!tree)
/*
* tree_init() returns success and a null tree
*/
return 1;
break;
- }
+ }
- if (!tree) goto error;
+ if (!tree)
+ goto error;
ret = tree_evaluate(tree);
tree_print("tree_evaluate()", tree, NULL);
goto error;
/* Return value 2 means tree empty */
- if (ret == 2)
- {
+ if (ret == 2) {
X509_policy_tree_free(tree);
if (*pexplicit_policy)
return -2;
else
return 1;
- }
+ }
/* Tree is not empty: continue */
if (!tree_calculate_user_set(tree, policy_oids, auth_nodes))
goto error;
-
+
if (ret == 2)
sk_X509_POLICY_NODE_free(auth_nodes);
if (tree)
*ptree = tree;
- if (*pexplicit_policy)
- {
+ if (*pexplicit_policy) {
nodes = X509_policy_tree_get0_user_policies(tree);
if (sk_X509_POLICY_NODE_num(nodes) <= 0)
return -2;
- }
+ }
return 1;
- error:
-
+error:
X509_policy_tree_free(tree);
return 0;
-
- }
-
+}