1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_citypedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ciDEFINE_STACK_OF(X509_POLICY_DATA)
13e1051a39Sopenharmony_ci
14e1051a39Sopenharmony_ci/* Internal structures */
15e1051a39Sopenharmony_ci
16e1051a39Sopenharmony_ci/*
17e1051a39Sopenharmony_ci * This structure and the field names correspond to the Policy 'node' of
18e1051a39Sopenharmony_ci * RFC3280. NB this structure contains no pointers to parent or child data:
19e1051a39Sopenharmony_ci * X509_POLICY_NODE contains that. This means that the main policy data can
20e1051a39Sopenharmony_ci * be kept static and cached with the certificate.
21e1051a39Sopenharmony_ci */
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_cistruct X509_POLICY_DATA_st {
24e1051a39Sopenharmony_ci    unsigned int flags;
25e1051a39Sopenharmony_ci    /* Policy OID and qualifiers for this data */
26e1051a39Sopenharmony_ci    ASN1_OBJECT *valid_policy;
27e1051a39Sopenharmony_ci    STACK_OF(POLICYQUALINFO) *qualifier_set;
28e1051a39Sopenharmony_ci    STACK_OF(ASN1_OBJECT) *expected_policy_set;
29e1051a39Sopenharmony_ci};
30e1051a39Sopenharmony_ci
31e1051a39Sopenharmony_ci/* X509_POLICY_DATA flags values */
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_ci/*
34e1051a39Sopenharmony_ci * This flag indicates the structure has been mapped using a policy mapping
35e1051a39Sopenharmony_ci * extension. If policy mapping is not active its references get deleted.
36e1051a39Sopenharmony_ci */
37e1051a39Sopenharmony_ci
38e1051a39Sopenharmony_ci#define POLICY_DATA_FLAG_MAPPED                 0x1
39e1051a39Sopenharmony_ci
40e1051a39Sopenharmony_ci/*
41e1051a39Sopenharmony_ci * This flag indicates the data doesn't correspond to a policy in Certificate
42e1051a39Sopenharmony_ci * Policies: it has been mapped to any policy.
43e1051a39Sopenharmony_ci */
44e1051a39Sopenharmony_ci
45e1051a39Sopenharmony_ci#define POLICY_DATA_FLAG_MAPPED_ANY             0x2
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_ci/* AND with flags to see if any mapping has occurred */
48e1051a39Sopenharmony_ci
49e1051a39Sopenharmony_ci#define POLICY_DATA_FLAG_MAP_MASK               0x3
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci/* qualifiers are shared and shouldn't be freed */
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ci#define POLICY_DATA_FLAG_SHARED_QUALIFIERS      0x4
54e1051a39Sopenharmony_ci
55e1051a39Sopenharmony_ci/* Parent node is an extra node and should be freed */
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ci#define POLICY_DATA_FLAG_EXTRA_NODE             0x8
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ci/* Corresponding CertificatePolicies is critical */
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ci#define POLICY_DATA_FLAG_CRITICAL               0x10
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_ci/* This structure is cached with a certificate */
64e1051a39Sopenharmony_ci
65e1051a39Sopenharmony_cistruct X509_POLICY_CACHE_st {
66e1051a39Sopenharmony_ci    /* anyPolicy data or NULL if no anyPolicy */
67e1051a39Sopenharmony_ci    X509_POLICY_DATA *anyPolicy;
68e1051a39Sopenharmony_ci    /* other policy data */
69e1051a39Sopenharmony_ci    STACK_OF(X509_POLICY_DATA) *data;
70e1051a39Sopenharmony_ci    /* If InhibitAnyPolicy present this is its value or -1 if absent. */
71e1051a39Sopenharmony_ci    long any_skip;
72e1051a39Sopenharmony_ci    /*
73e1051a39Sopenharmony_ci     * If policyConstraints and requireExplicitPolicy present this is its
74e1051a39Sopenharmony_ci     * value or -1 if absent.
75e1051a39Sopenharmony_ci     */
76e1051a39Sopenharmony_ci    long explicit_skip;
77e1051a39Sopenharmony_ci    /*
78e1051a39Sopenharmony_ci     * If policyConstraints and policyMapping present this is its value or -1
79e1051a39Sopenharmony_ci     * if absent.
80e1051a39Sopenharmony_ci     */
81e1051a39Sopenharmony_ci    long map_skip;
82e1051a39Sopenharmony_ci};
83e1051a39Sopenharmony_ci
84e1051a39Sopenharmony_ci/*
85e1051a39Sopenharmony_ci * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL
86e1051a39Sopenharmony_ci */
87e1051a39Sopenharmony_ci
88e1051a39Sopenharmony_ci/* This structure represents the relationship between nodes */
89e1051a39Sopenharmony_ci
90e1051a39Sopenharmony_cistruct X509_POLICY_NODE_st {
91e1051a39Sopenharmony_ci    /* node data this refers to */
92e1051a39Sopenharmony_ci    const X509_POLICY_DATA *data;
93e1051a39Sopenharmony_ci    /* Parent node */
94e1051a39Sopenharmony_ci    X509_POLICY_NODE *parent;
95e1051a39Sopenharmony_ci    /* Number of child nodes */
96e1051a39Sopenharmony_ci    int nchild;
97e1051a39Sopenharmony_ci};
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_cistruct X509_POLICY_LEVEL_st {
100e1051a39Sopenharmony_ci    /* Cert for this level */
101e1051a39Sopenharmony_ci    X509 *cert;
102e1051a39Sopenharmony_ci    /* nodes at this level */
103e1051a39Sopenharmony_ci    STACK_OF(X509_POLICY_NODE) *nodes;
104e1051a39Sopenharmony_ci    /* anyPolicy node */
105e1051a39Sopenharmony_ci    X509_POLICY_NODE *anyPolicy;
106e1051a39Sopenharmony_ci    /* Extra data */
107e1051a39Sopenharmony_ci    /*
108e1051a39Sopenharmony_ci     * STACK_OF(X509_POLICY_DATA) *extra_data;
109e1051a39Sopenharmony_ci     */
110e1051a39Sopenharmony_ci    unsigned int flags;
111e1051a39Sopenharmony_ci};
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_cistruct X509_POLICY_TREE_st {
114e1051a39Sopenharmony_ci    /* The number of nodes in the tree */
115e1051a39Sopenharmony_ci    size_t node_count;
116e1051a39Sopenharmony_ci    /* The maximum number of nodes in the tree */
117e1051a39Sopenharmony_ci    size_t node_maximum;
118e1051a39Sopenharmony_ci
119e1051a39Sopenharmony_ci    /* This is the tree 'level' data */
120e1051a39Sopenharmony_ci    X509_POLICY_LEVEL *levels;
121e1051a39Sopenharmony_ci    int nlevel;
122e1051a39Sopenharmony_ci    /*
123e1051a39Sopenharmony_ci     * Extra policy data when additional nodes (not from the certificate) are
124e1051a39Sopenharmony_ci     * required.
125e1051a39Sopenharmony_ci     */
126e1051a39Sopenharmony_ci    STACK_OF(X509_POLICY_DATA) *extra_data;
127e1051a39Sopenharmony_ci    /* This is the authority constrained policy set */
128e1051a39Sopenharmony_ci    STACK_OF(X509_POLICY_NODE) *auth_policies;
129e1051a39Sopenharmony_ci    STACK_OF(X509_POLICY_NODE) *user_policies;
130e1051a39Sopenharmony_ci    unsigned int flags;
131e1051a39Sopenharmony_ci};
132e1051a39Sopenharmony_ci
133e1051a39Sopenharmony_ci/* Set if anyPolicy present in user policies */
134e1051a39Sopenharmony_ci#define POLICY_FLAG_ANY_POLICY          0x2
135e1051a39Sopenharmony_ci
136e1051a39Sopenharmony_ci/* Useful macros */
137e1051a39Sopenharmony_ci
138e1051a39Sopenharmony_ci#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
139e1051a39Sopenharmony_ci#define node_critical(node) node_data_critical(node->data)
140e1051a39Sopenharmony_ci
141e1051a39Sopenharmony_ci/* Internal functions */
142e1051a39Sopenharmony_ci
143e1051a39Sopenharmony_ciX509_POLICY_DATA *ossl_policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
144e1051a39Sopenharmony_ci                                       int crit);
145e1051a39Sopenharmony_civoid ossl_policy_data_free(X509_POLICY_DATA *data);
146e1051a39Sopenharmony_ci
147e1051a39Sopenharmony_ciX509_POLICY_DATA *ossl_policy_cache_find_data(const X509_POLICY_CACHE *cache,
148e1051a39Sopenharmony_ci                                              const ASN1_OBJECT *id);
149e1051a39Sopenharmony_ciint ossl_policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
150e1051a39Sopenharmony_ci
151e1051a39Sopenharmony_ciSTACK_OF(X509_POLICY_NODE) *ossl_policy_node_cmp_new(void);
152e1051a39Sopenharmony_ci
153e1051a39Sopenharmony_civoid ossl_policy_cache_free(X509_POLICY_CACHE *cache);
154e1051a39Sopenharmony_ci
155e1051a39Sopenharmony_ciX509_POLICY_NODE *ossl_policy_level_find_node(const X509_POLICY_LEVEL *level,
156e1051a39Sopenharmony_ci                                              const X509_POLICY_NODE *parent,
157e1051a39Sopenharmony_ci                                              const ASN1_OBJECT *id);
158e1051a39Sopenharmony_ci
159e1051a39Sopenharmony_ciX509_POLICY_NODE *ossl_policy_tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
160e1051a39Sopenharmony_ci                                           const ASN1_OBJECT *id);
161e1051a39Sopenharmony_ci
162e1051a39Sopenharmony_ciX509_POLICY_NODE *ossl_policy_level_add_node(X509_POLICY_LEVEL *level,
163e1051a39Sopenharmony_ci                                             X509_POLICY_DATA *data,
164e1051a39Sopenharmony_ci                                             X509_POLICY_NODE *parent,
165e1051a39Sopenharmony_ci                                             X509_POLICY_TREE *tree,
166e1051a39Sopenharmony_ci                                             int extra_data);
167e1051a39Sopenharmony_civoid ossl_policy_node_free(X509_POLICY_NODE *node);
168e1051a39Sopenharmony_ciint ossl_policy_node_match(const X509_POLICY_LEVEL *lvl,
169e1051a39Sopenharmony_ci                           const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
170e1051a39Sopenharmony_ci
171e1051a39Sopenharmony_ciconst X509_POLICY_CACHE *ossl_policy_cache_set(X509 *x);
172