pcy_cache.c
Go to the documentation of this file.
1 /*
2  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3  * 2004.
4  */
5 /* ====================================================================
6  * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  * software must display the following acknowledgment:
22  * "This product includes software developed by the OpenSSL Project
23  * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  * endorse or promote products derived from this software without
27  * prior written permission. For written permission, please contact
28  * licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  * nor may "OpenSSL" appear in their names without prior written
32  * permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  * acknowledgment:
36  * "This product includes software developed by the OpenSSL Project
37  * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com). This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com). */
56 
57 #include <openssl/mem.h>
58 #include <openssl/obj.h>
59 #include <openssl/thread.h>
60 #include <openssl/x509.h>
61 #include <openssl/x509v3.h>
62 
63 #include "../internal.h"
64 #include "../x509/internal.h"
65 #include "internal.h"
66 
67 static int policy_data_cmp(const X509_POLICY_DATA **a,
68  const X509_POLICY_DATA **b);
69 static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
70 
71 /*
72  * Set cache entry according to CertificatePolicies extension. Note: this
73  * destroys the passed CERTIFICATEPOLICIES structure.
74  */
75 
77  CERTIFICATEPOLICIES *policies, int crit)
78 {
79  size_t i;
80  int ret = 0;
81  X509_POLICY_CACHE *cache = x->policy_cache;
82  X509_POLICY_DATA *data = NULL;
83  POLICYINFO *policy;
84  if (sk_POLICYINFO_num(policies) == 0)
85  goto bad_policy;
86  cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
87  if (!cache->data)
88  goto bad_policy;
89  for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
90  policy = sk_POLICYINFO_value(policies, i);
91  data = policy_data_new(policy, NULL, crit);
92  if (!data)
93  goto bad_policy;
94  /*
95  * Duplicate policy OIDs are illegal: reject if matches found.
96  */
97  sk_X509_POLICY_DATA_sort(cache->data);
98  if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
99  if (cache->anyPolicy) {
100  ret = -1;
101  goto bad_policy;
102  }
103  cache->anyPolicy = data;
104  } else if (sk_X509_POLICY_DATA_find(cache->data, NULL, data)) {
105  ret = -1;
106  goto bad_policy;
107  } else if (!sk_X509_POLICY_DATA_push(cache->data, data))
108  goto bad_policy;
109  data = NULL;
110  }
111  ret = 1;
112  bad_policy:
113  if (ret == -1)
114  x->ex_flags |= EXFLAG_INVALID_POLICY;
115  if (data)
117  sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
118  if (ret <= 0) {
119  sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
120  cache->data = NULL;
121  }
122  return ret;
123 }
124 
125 static int policy_cache_new(X509 *x)
126 {
127  X509_POLICY_CACHE *cache;
128  ASN1_INTEGER *ext_any = NULL;
129  POLICY_CONSTRAINTS *ext_pcons = NULL;
130  CERTIFICATEPOLICIES *ext_cpols = NULL;
131  POLICY_MAPPINGS *ext_pmaps = NULL;
132  int i;
133  cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE));
134  if (!cache)
135  return 0;
136  cache->anyPolicy = NULL;
137  cache->data = NULL;
138  cache->any_skip = -1;
139  cache->explicit_skip = -1;
140  cache->map_skip = -1;
141 
142  x->policy_cache = cache;
143 
144  /*
145  * Handle requireExplicitPolicy *first*. Need to process this even if we
146  * don't have any policies.
147  */
148  ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
149 
150  if (!ext_pcons) {
151  if (i != -1)
152  goto bad_cache;
153  } else {
154  if (!ext_pcons->requireExplicitPolicy
155  && !ext_pcons->inhibitPolicyMapping)
156  goto bad_cache;
157  if (!policy_cache_set_int(&cache->explicit_skip,
158  ext_pcons->requireExplicitPolicy))
159  goto bad_cache;
160  if (!policy_cache_set_int(&cache->map_skip,
161  ext_pcons->inhibitPolicyMapping))
162  goto bad_cache;
163  }
164 
165  /* Process CertificatePolicies */
166 
167  ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
168  /*
169  * If no CertificatePolicies extension or problem decoding then there is
170  * no point continuing because the valid policies will be NULL.
171  */
172  if (!ext_cpols) {
173  /* If not absent some problem with extension */
174  if (i != -1)
175  goto bad_cache;
176  return 1;
177  }
178 
179  i = policy_cache_create(x, ext_cpols, i);
180 
181  /* NB: ext_cpols freed by policy_cache_set_policies */
182 
183  if (i <= 0)
184  return i;
185 
186  ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
187 
188  if (!ext_pmaps) {
189  /* If not absent some problem with extension */
190  if (i != -1)
191  goto bad_cache;
192  } else {
193  i = policy_cache_set_mapping(x, ext_pmaps);
194  if (i <= 0)
195  goto bad_cache;
196  }
197 
198  ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
199 
200  if (!ext_any) {
201  if (i != -1)
202  goto bad_cache;
203  } else if (!policy_cache_set_int(&cache->any_skip, ext_any))
204  goto bad_cache;
205 
206  if (0) {
207  bad_cache:
208  x->ex_flags |= EXFLAG_INVALID_POLICY;
209  }
210 
211  if (ext_pcons)
212  POLICY_CONSTRAINTS_free(ext_pcons);
213 
214  if (ext_any)
215  ASN1_INTEGER_free(ext_any);
216 
217  return 1;
218 
219 }
220 
222 {
223  if (!cache)
224  return;
225  if (cache->anyPolicy)
226  policy_data_free(cache->anyPolicy);
227  if (cache->data)
228  sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
229  OPENSSL_free(cache);
230 }
231 
232 /*
233  * g_x509_policy_cache_lock is used to protect against concurrent calls to
234  * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t| in
235  * the |X509| structure, but |CRYPTO_once_t| isn't public.
236  */
239 
241 {
242  X509_POLICY_CACHE *cache;
243 
245  cache = x->policy_cache;
247 
248  if (cache != NULL)
249  return cache;
250 
252  if (x->policy_cache == NULL)
254  cache = x->policy_cache;
256 
257  return cache;
258 }
259 
261  const ASN1_OBJECT *id)
262 {
263  size_t idx;
265 
266  tmp.valid_policy = (ASN1_OBJECT *)id;
267  sk_X509_POLICY_DATA_sort(cache->data);
268  if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp))
269  return NULL;
270  return sk_X509_POLICY_DATA_value(cache->data, idx);
271 }
272 
273 static int policy_data_cmp(const X509_POLICY_DATA **a,
274  const X509_POLICY_DATA **b)
275 {
276  return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
277 }
278 
280 {
281  if (value == NULL)
282  return 1;
283  if (value->type == V_ASN1_NEG_INTEGER)
284  return 0;
286  return 1;
287 }
NID_policy_mappings
#define NID_policy_mappings
Definition: nid.h:3298
CRYPTO_STATIC_MUTEX_INIT
#define CRYPTO_STATIC_MUTEX_INIT
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:536
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
policy_data_free
#define policy_data_free
Definition: boringssl_prefix_symbols.h:3349
POLICYINFO_st
Definition: x509v3.h:284
X509_POLICY_CACHE_st::any_skip
long any_skip
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:186
CRYPTO_STATIC_MUTEX_unlock_write
#define CRYPTO_STATIC_MUTEX_unlock_write
Definition: boringssl_prefix_symbols.h:1135
POLICY_CONSTRAINTS_free
#define POLICY_CONSTRAINTS_free
Definition: boringssl_prefix_symbols.h:2044
internal.h
X509_POLICY_CACHE_st::anyPolicy
X509_POLICY_DATA * anyPolicy
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:182
ASN1_INTEGER_get
#define ASN1_INTEGER_get
Definition: boringssl_prefix_symbols.h:645
x509v3.h
POLICY_CONSTRAINTS_st
Definition: x509v3.h:315
POLICY_CONSTRAINTS_st::inhibitPolicyMapping
ASN1_INTEGER * inhibitPolicyMapping
Definition: x509v3.h:317
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
asn1_object_st
Definition: third_party/boringssl-with-bazel/src/crypto/asn1/internal.h:102
OPENSSL_malloc
#define OPENSSL_malloc
Definition: boringssl_prefix_symbols.h:1885
CRYPTO_STATIC_MUTEX
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:533
OBJ_obj2nid
#define OBJ_obj2nid
Definition: boringssl_prefix_symbols.h:1857
g_x509_policy_cache_lock
static struct CRYPTO_STATIC_MUTEX g_x509_policy_cache_lock
Definition: pcy_cache.c:237
POLICY_CONSTRAINTS_st::requireExplicitPolicy
ASN1_INTEGER * requireExplicitPolicy
Definition: x509v3.h:316
X509_POLICY_CACHE_st::explicit_skip
long explicit_skip
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:191
EXFLAG_INVALID_POLICY
#define EXFLAG_INVALID_POLICY
Definition: x509v3.h:401
CRYPTO_STATIC_MUTEX_unlock_read
#define CRYPTO_STATIC_MUTEX_unlock_read
Definition: boringssl_prefix_symbols.h:1134
CRYPTO_STATIC_MUTEX_lock_write
#define CRYPTO_STATIC_MUTEX_lock_write
Definition: boringssl_prefix_symbols.h:1133
policy_cache_set_int
static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
Definition: pcy_cache.c:279
NID_any_policy
#define NID_any_policy
Definition: nid.h:3293
policy_cache_set_mapping
#define policy_cache_set_mapping
Definition: boringssl_prefix_symbols.h:3348
policy_cache_create
static int policy_cache_create(X509 *x, CERTIFICATEPOLICIES *policies, int crit)
Definition: pcy_cache.c:76
NID_inhibit_any_policy
#define NID_inhibit_any_policy
Definition: nid.h:3303
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
POLICYINFO_free
#define POLICYINFO_free
Definition: boringssl_prefix_symbols.h:2038
ASN1_INTEGER_free
OPENSSL_EXPORT void ASN1_INTEGER_free(ASN1_INTEGER *str)
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
setup.idx
idx
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:197
OBJ_cmp
#define OBJ_cmp
Definition: boringssl_prefix_symbols.h:1845
X509_POLICY_DATA_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:138
value
const char * value
Definition: hpack_parser_table.cc:165
policy_data_cmp
static int policy_data_cmp(const X509_POLICY_DATA **a, const X509_POLICY_DATA **b)
Definition: pcy_cache.c:273
policy_cache_find_data
X509_POLICY_DATA * policy_cache_find_data(const X509_POLICY_CACHE *cache, const ASN1_OBJECT *id)
Definition: pcy_cache.c:260
NID_policy_constraints
#define NID_policy_constraints
Definition: nid.h:1859
policy_cache_new
static int policy_cache_new(X509 *x)
Definition: pcy_cache.c:125
policy_cache_set
const X509_POLICY_CACHE * policy_cache_set(X509 *x)
Definition: pcy_cache.c:240
x509_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509/internal.h:139
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
X509_POLICY_CACHE_st::map_skip
long map_skip
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:196
X509_get_ext_d2i
#define X509_get_ext_d2i
Definition: boringssl_prefix_symbols.h:2661
policy_cache_free
void policy_cache_free(X509_POLICY_CACHE *cache)
Definition: pcy_cache.c:221
obj.h
policy_data_new
#define policy_data_new
Definition: boringssl_prefix_symbols.h:3350
CRYPTO_STATIC_MUTEX_lock_read
#define CRYPTO_STATIC_MUTEX_lock_read
Definition: boringssl_prefix_symbols.h:1132
mem.h
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
X509_POLICY_CACHE_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509v3/internal.h:180
thread.h
OPENSSL_free
#define OPENSSL_free
Definition: boringssl_prefix_symbols.h:1869
NID_certificate_policies
#define NID_certificate_policies
Definition: nid.h:494
V_ASN1_NEG_INTEGER
#define V_ASN1_NEG_INTEGER
Definition: asn1.h:156
asn1_string_st
Definition: asn1.h:543
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
x509.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:41