summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
committercvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
commiteb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch)
treeedb6da6af7e865d488dc1a29309f1e1ec226e603 /src/lib/libcrypto/x509
parent247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff)
downloadopenbsd-tb_20250414.tar.gz
openbsd-tb_20250414.tar.bz2
openbsd-tb_20250414.zip
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/lib/libcrypto/x509')
-rw-r--r--src/lib/libcrypto/x509/by_dir.c407
-rw-r--r--src/lib/libcrypto/x509/by_file.c262
-rw-r--r--src/lib/libcrypto/x509/by_mem.c136
-rw-r--r--src/lib/libcrypto/x509/x509.h1041
-rw-r--r--src/lib/libcrypto/x509/x509_addr.c2074
-rw-r--r--src/lib/libcrypto/x509/x509_akey.c245
-rw-r--r--src/lib/libcrypto/x509/x509_akeya.c129
-rw-r--r--src/lib/libcrypto/x509/x509_alt.c799
-rw-r--r--src/lib/libcrypto/x509/x509_asid.c1255
-rw-r--r--src/lib/libcrypto/x509/x509_att.c377
-rw-r--r--src/lib/libcrypto/x509/x509_bcons.c212
-rw-r--r--src/lib/libcrypto/x509/x509_bitst.c240
-rw-r--r--src/lib/libcrypto/x509/x509_cmp.c429
-rw-r--r--src/lib/libcrypto/x509/x509_conf.c456
-rw-r--r--src/lib/libcrypto/x509/x509_constraints.c1294
-rw-r--r--src/lib/libcrypto/x509/x509_cpols.c773
-rw-r--r--src/lib/libcrypto/x509/x509_crld.c852
-rw-r--r--src/lib/libcrypto/x509/x509_d2.c131
-rw-r--r--src/lib/libcrypto/x509/x509_def.c103
-rw-r--r--src/lib/libcrypto/x509/x509_err.c215
-rw-r--r--src/lib/libcrypto/x509/x509_ext.c258
-rw-r--r--src/lib/libcrypto/x509/x509_extku.c236
-rw-r--r--src/lib/libcrypto/x509/x509_genn.c541
-rw-r--r--src/lib/libcrypto/x509/x509_ia5.c268
-rw-r--r--src/lib/libcrypto/x509/x509_info.c331
-rw-r--r--src/lib/libcrypto/x509/x509_int.c136
-rw-r--r--src/lib/libcrypto/x509/x509_internal.h141
-rw-r--r--src/lib/libcrypto/x509/x509_issuer_cache.c193
-rw-r--r--src/lib/libcrypto/x509/x509_issuer_cache.h48
-rw-r--r--src/lib/libcrypto/x509/x509_lib.c374
-rw-r--r--src/lib/libcrypto/x509/x509_local.h503
-rw-r--r--src/lib/libcrypto/x509/x509_lu.c883
-rw-r--r--src/lib/libcrypto/x509/x509_ncons.c569
-rw-r--r--src/lib/libcrypto/x509/x509_obj.c198
-rw-r--r--src/lib/libcrypto/x509/x509_ocsp.c424
-rw-r--r--src/lib/libcrypto/x509/x509_pcons.c205
-rw-r--r--src/lib/libcrypto/x509/x509_pku.c165
-rw-r--r--src/lib/libcrypto/x509/x509_pmaps.c247
-rw-r--r--src/lib/libcrypto/x509/x509_policy.c1018
-rw-r--r--src/lib/libcrypto/x509/x509_prn.c231
-rw-r--r--src/lib/libcrypto/x509/x509_purp.c930
-rw-r--r--src/lib/libcrypto/x509/x509_r2x.c117
-rw-r--r--src/lib/libcrypto/x509/x509_req.c320
-rw-r--r--src/lib/libcrypto/x509/x509_set.c268
-rw-r--r--src/lib/libcrypto/x509/x509_siginfo.c113
-rw-r--r--src/lib/libcrypto/x509/x509_skey.c171
-rw-r--r--src/lib/libcrypto/x509/x509_trs.c173
-rw-r--r--src/lib/libcrypto/x509/x509_txt.c196
-rw-r--r--src/lib/libcrypto/x509/x509_utl.c1494
-rw-r--r--src/lib/libcrypto/x509/x509_v3.c295
-rw-r--r--src/lib/libcrypto/x509/x509_verify.c1288
-rw-r--r--src/lib/libcrypto/x509/x509_verify.h43
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c2602
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.h463
-rw-r--r--src/lib/libcrypto/x509/x509_vpm.c743
-rw-r--r--src/lib/libcrypto/x509/x509cset.c238
-rw-r--r--src/lib/libcrypto/x509/x509name.c452
-rw-r--r--src/lib/libcrypto/x509/x509rset.c113
-rw-r--r--src/lib/libcrypto/x509/x509spki.c136
-rw-r--r--src/lib/libcrypto/x509/x509type.c136
-rw-r--r--src/lib/libcrypto/x509/x509v3.h1041
-rw-r--r--src/lib/libcrypto/x509/x_all.c536
62 files changed, 0 insertions, 30267 deletions
diff --git a/src/lib/libcrypto/x509/by_dir.c b/src/lib/libcrypto/x509/by_dir.c
deleted file mode 100644
index 2b2733a04b..0000000000
--- a/src/lib/libcrypto/x509/by_dir.c
+++ /dev/null
@@ -1,407 +0,0 @@
1/* $OpenBSD: by_dir.c,v 1.48 2024/08/31 10:19:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <errno.h>
60#include <stdio.h>
61#include <string.h>
62#include <time.h>
63#include <unistd.h>
64
65#include <openssl/opensslconf.h>
66
67#include <openssl/err.h>
68#include <openssl/x509.h>
69
70#include "x509_local.h"
71
72typedef struct lookup_dir_hashes_st {
73 unsigned long hash;
74 int suffix;
75} BY_DIR_HASH;
76
77typedef struct lookup_dir_entry_st {
78 char *dir;
79 int dir_type;
80 STACK_OF(BY_DIR_HASH) *hashes;
81} BY_DIR_ENTRY;
82
83typedef struct lookup_dir_st {
84 BUF_MEM *buffer;
85 STACK_OF(BY_DIR_ENTRY) *dirs;
86} BY_DIR;
87
88DECLARE_STACK_OF(BY_DIR_HASH)
89DECLARE_STACK_OF(BY_DIR_ENTRY)
90
91static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
92 char **ret);
93static int new_dir(X509_LOOKUP *lu);
94static void free_dir(X509_LOOKUP *lu);
95static int add_cert_dir(BY_DIR *ctx, const char *dir, int type);
96static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
97 X509_OBJECT *ret);
98
99static const X509_LOOKUP_METHOD x509_dir_lookup = {
100 .name = "Load certs from files in a directory",
101 .new_item = new_dir,
102 .free = free_dir,
103 .ctrl = dir_ctrl,
104 .get_by_subject = get_cert_by_subject,
105};
106
107const X509_LOOKUP_METHOD *
108X509_LOOKUP_hash_dir(void)
109{
110 return &x509_dir_lookup;
111}
112LCRYPTO_ALIAS(X509_LOOKUP_hash_dir);
113
114static int
115dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
116 char **retp)
117{
118 BY_DIR *ld = ctx->method_data;
119 int ret = 0;
120
121 switch (cmd) {
122 case X509_L_ADD_DIR:
123 if (argl == X509_FILETYPE_DEFAULT) {
124 ret = add_cert_dir(ld, X509_get_default_cert_dir(),
125 X509_FILETYPE_PEM);
126 if (!ret) {
127 X509error(X509_R_LOADING_CERT_DIR);
128 }
129 } else
130 ret = add_cert_dir(ld, argp, (int)argl);
131 break;
132 }
133 return ret;
134}
135
136static int
137new_dir(X509_LOOKUP *lu)
138{
139 BY_DIR *a;
140
141 if ((a = malloc(sizeof(*a))) == NULL) {
142 X509error(ERR_R_MALLOC_FAILURE);
143 return 0;
144 }
145 if ((a->buffer = BUF_MEM_new()) == NULL) {
146 X509error(ERR_R_MALLOC_FAILURE);
147 free(a);
148 return 0;
149 }
150 a->dirs = NULL;
151 lu->method_data = a;
152 return 1;
153}
154
155static void
156by_dir_hash_free(BY_DIR_HASH *hash)
157{
158 free(hash);
159}
160
161static int
162by_dir_hash_cmp(const BY_DIR_HASH * const *a,
163 const BY_DIR_HASH * const *b)
164{
165 if ((*a)->hash > (*b)->hash)
166 return 1;
167 if ((*a)->hash < (*b)->hash)
168 return -1;
169 return 0;
170}
171
172static void
173by_dir_entry_free(BY_DIR_ENTRY *ent)
174{
175 free(ent->dir);
176 sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
177 free(ent);
178}
179
180static void
181free_dir(X509_LOOKUP *lu)
182{
183 BY_DIR *a;
184
185 a = lu->method_data;
186 sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
187 BUF_MEM_free(a->buffer);
188 free(a);
189}
190
191static int
192add_cert_dir(BY_DIR *ctx, const char *dir, int type)
193{
194 int j;
195 const char *s, *ss, *p;
196 ptrdiff_t len;
197
198 if (dir == NULL || !*dir) {
199 X509error(X509_R_INVALID_DIRECTORY);
200 return 0;
201 }
202
203 s = dir;
204 p = s;
205 do {
206 if ((*p == ':') || (*p == '\0')) {
207 BY_DIR_ENTRY *ent;
208
209 ss = s;
210 s = p + 1;
211 len = p - ss;
212 if (len == 0)
213 continue;
214 for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) {
215 ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
216 if (strlen(ent->dir) == (size_t)len &&
217 strncmp(ent->dir, ss, (size_t)len) == 0)
218 break;
219 }
220 if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
221 continue;
222 if (ctx->dirs == NULL) {
223 ctx->dirs = sk_BY_DIR_ENTRY_new_null();
224 if (ctx->dirs == NULL) {
225 X509error(ERR_R_MALLOC_FAILURE);
226 return 0;
227 }
228 }
229 ent = malloc(sizeof(*ent));
230 if (ent == NULL) {
231 X509error(ERR_R_MALLOC_FAILURE);
232 return 0;
233 }
234 ent->dir_type = type;
235 ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
236 ent->dir = strndup(ss, (size_t)len);
237 if (ent->dir == NULL || ent->hashes == NULL) {
238 X509error(ERR_R_MALLOC_FAILURE);
239 by_dir_entry_free(ent);
240 return 0;
241 }
242 if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) {
243 X509error(ERR_R_MALLOC_FAILURE);
244 by_dir_entry_free(ent);
245 return 0;
246 }
247 }
248 } while (*p++ != '\0');
249 return 1;
250}
251
252static int
253get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
254 X509_OBJECT *ret)
255{
256 BY_DIR *ctx;
257 union {
258 struct {
259 X509 st_x509;
260 X509_CINF st_x509_cinf;
261 } x509;
262 struct {
263 X509_CRL st_crl;
264 X509_CRL_INFO st_crl_info;
265 } crl;
266 } data;
267 int ok = 0;
268 int i, j, k;
269 unsigned long h;
270 BUF_MEM *b = NULL;
271 X509_OBJECT stmp, *tmp;
272 const char *postfix="";
273
274 if (name == NULL)
275 return 0;
276
277 stmp.type = type;
278 if (type == X509_LU_X509) {
279 data.x509.st_x509.cert_info = &data.x509.st_x509_cinf;
280 data.x509.st_x509_cinf.subject = name;
281 stmp.data.x509 = &data.x509.st_x509;
282 postfix="";
283 } else if (type == X509_LU_CRL) {
284 data.crl.st_crl.crl = &data.crl.st_crl_info;
285 data.crl.st_crl_info.issuer = name;
286 stmp.data.crl = &data.crl.st_crl;
287 postfix="r";
288 } else {
289 X509error(X509_R_WRONG_LOOKUP_TYPE);
290 goto finish;
291 }
292
293 if ((b = BUF_MEM_new()) == NULL) {
294 X509error(ERR_R_BUF_LIB);
295 goto finish;
296 }
297
298 ctx = xl->method_data;
299
300 h = X509_NAME_hash(name);
301 for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) {
302 BY_DIR_ENTRY *ent;
303 int idx;
304 BY_DIR_HASH htmp, *hent;
305
306 ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
307 j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1;
308 if (!BUF_MEM_grow(b, j)) {
309 X509error(ERR_R_MALLOC_FAILURE);
310 goto finish;
311 }
312 if (type == X509_LU_CRL) {
313 htmp.hash = h;
314 CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
315 idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
316 if (idx >= 0) {
317 hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
318 k = hent->suffix;
319 } else {
320 hent = NULL;
321 k = 0;
322 }
323 CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
324 } else {
325 k = 0;
326 hent = NULL;
327 }
328 for (;;) {
329 (void) snprintf(b->data, b->max, "%s/%08lx.%s%d",
330 ent->dir, h, postfix, k);
331 /*
332 * Found one. Attempt to load it. This could fail for
333 * any number of reasons from the file can't be opened,
334 * the file contains garbage, etc. Clear the error stack
335 * to avoid exposing the lower level error. These all
336 * boil down to "we could not find CA/CRL".
337 */
338 if (type == X509_LU_X509) {
339 if ((X509_load_cert_file(xl, b->data,
340 ent->dir_type)) == 0) {
341 ERR_clear_error();
342 break;
343 }
344 } else if (type == X509_LU_CRL) {
345 if ((X509_load_crl_file(xl, b->data,
346 ent->dir_type)) == 0) {
347 ERR_clear_error();
348 break;
349 }
350 }
351 /* The lack of a CA or CRL will be caught higher up. */
352 k++;
353 }
354
355 /* we have added it to the cache so now pull it out again */
356 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
357 j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp);
358 tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
359 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
360
361 /* If a CRL, update the last file suffix added for this */
362 if (type == X509_LU_CRL) {
363 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
364 /*
365 * Look for entry again in case another thread added
366 * an entry first.
367 */
368 if (hent == NULL) {
369 htmp.hash = h;
370 idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
371 hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
372 }
373 if (hent == NULL) {
374 hent = malloc(sizeof(*hent));
375 if (hent == NULL) {
376 X509error(ERR_R_MALLOC_FAILURE);
377 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
378 ok = 0;
379 goto finish;
380 }
381 hent->hash = h;
382 hent->suffix = k;
383 if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
384 X509error(ERR_R_MALLOC_FAILURE);
385 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
386 free(hent);
387 ok = 0;
388 goto finish;
389 }
390 } else if (hent->suffix < k)
391 hent->suffix = k;
392
393 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
394
395 }
396
397 if (tmp != NULL) {
398 ok = 1;
399 ret->type = tmp->type;
400 memcpy(&ret->data, &tmp->data, sizeof(ret->data));
401 goto finish;
402 }
403 }
404finish:
405 BUF_MEM_free(b);
406 return ok;
407}
diff --git a/src/lib/libcrypto/x509/by_file.c b/src/lib/libcrypto/x509/by_file.c
deleted file mode 100644
index 9b0fd2542c..0000000000
--- a/src/lib/libcrypto/x509/by_file.c
+++ /dev/null
@@ -1,262 +0,0 @@
1/* $OpenBSD: by_file.c,v 1.31 2024/08/31 10:19:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <errno.h>
60#include <stdio.h>
61#include <time.h>
62#include <unistd.h>
63
64#include <openssl/buffer.h>
65#include <openssl/err.h>
66#include <openssl/pem.h>
67#include <openssl/x509.h>
68
69#include "x509_local.h"
70
71static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
72 long argl, char **ret);
73
74static const X509_LOOKUP_METHOD x509_file_lookup = {
75 .name = "Load file into cache",
76 .new_item = NULL,
77 .free = NULL,
78 .ctrl = by_file_ctrl,
79 .get_by_subject = NULL,
80};
81
82const X509_LOOKUP_METHOD *
83X509_LOOKUP_file(void)
84{
85 return &x509_file_lookup;
86}
87LCRYPTO_ALIAS(X509_LOOKUP_file);
88
89static int
90by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
91 char **ret)
92{
93 const char *file = argp;
94 int type = argl;
95
96 if (cmd != X509_L_FILE_LOAD)
97 return 0;
98
99 if (argl == X509_FILETYPE_DEFAULT) {
100 file = X509_get_default_cert_file();
101 type = X509_FILETYPE_PEM;
102 }
103 if (X509_load_cert_crl_file(ctx, file, type) != 0)
104 return 1;
105 if (argl == X509_FILETYPE_DEFAULT)
106 X509error(X509_R_LOADING_DEFAULTS);
107
108 return 0;
109}
110
111int
112X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
113{
114 int ret = 0;
115 BIO *in = NULL;
116 int i, count = 0;
117 X509 *x = NULL;
118
119 in = BIO_new(BIO_s_file());
120
121 if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
122 X509error(ERR_R_SYS_LIB);
123 goto err;
124 }
125
126 if (type == X509_FILETYPE_PEM) {
127 for (;;) {
128 x = PEM_read_bio_X509_AUX(in, NULL, NULL, "");
129 if (x == NULL) {
130 if ((ERR_GET_REASON(ERR_peek_last_error()) ==
131 PEM_R_NO_START_LINE) && (count > 0)) {
132 ERR_clear_error();
133 break;
134 } else {
135 X509error(ERR_R_PEM_LIB);
136 goto err;
137 }
138 }
139 i = X509_STORE_add_cert(ctx->store_ctx, x);
140 if (!i)
141 goto err;
142 count++;
143 X509_free(x);
144 x = NULL;
145 }
146 ret = count;
147 } else if (type == X509_FILETYPE_ASN1) {
148 x = d2i_X509_bio(in, NULL);
149 if (x == NULL) {
150 X509error(ERR_R_ASN1_LIB);
151 goto err;
152 }
153 i = X509_STORE_add_cert(ctx->store_ctx, x);
154 if (!i)
155 goto err;
156 ret = i;
157 } else {
158 X509error(X509_R_BAD_X509_FILETYPE);
159 goto err;
160 }
161err:
162 X509_free(x);
163 BIO_free(in);
164 return ret;
165}
166LCRYPTO_ALIAS(X509_load_cert_file);
167
168int
169X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
170{
171 int ret = 0;
172 BIO *in = NULL;
173 int i, count = 0;
174 X509_CRL *x = NULL;
175
176 in = BIO_new(BIO_s_file());
177
178 if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
179 X509error(ERR_R_SYS_LIB);
180 goto err;
181 }
182
183 if (type == X509_FILETYPE_PEM) {
184 for (;;) {
185 x = PEM_read_bio_X509_CRL(in, NULL, NULL, "");
186 if (x == NULL) {
187 if ((ERR_GET_REASON(ERR_peek_last_error()) ==
188 PEM_R_NO_START_LINE) && (count > 0)) {
189 ERR_clear_error();
190 break;
191 } else {
192 X509error(ERR_R_PEM_LIB);
193 goto err;
194 }
195 }
196 i = X509_STORE_add_crl(ctx->store_ctx, x);
197 if (!i)
198 goto err;
199 count++;
200 X509_CRL_free(x);
201 x = NULL;
202 }
203 ret = count;
204 } else if (type == X509_FILETYPE_ASN1) {
205 x = d2i_X509_CRL_bio(in, NULL);
206 if (x == NULL) {
207 X509error(ERR_R_ASN1_LIB);
208 goto err;
209 }
210 i = X509_STORE_add_crl(ctx->store_ctx, x);
211 if (!i)
212 goto err;
213 ret = i;
214 } else {
215 X509error(X509_R_BAD_X509_FILETYPE);
216 goto err;
217 }
218err:
219 X509_CRL_free(x);
220 BIO_free(in);
221 return ret;
222}
223LCRYPTO_ALIAS(X509_load_crl_file);
224
225int
226X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
227{
228 STACK_OF(X509_INFO) *inf;
229 X509_INFO *itmp;
230 BIO *in;
231 int i, count = 0;
232
233 if (type != X509_FILETYPE_PEM)
234 return X509_load_cert_file(ctx, file, type);
235 in = BIO_new_file(file, "r");
236 if (!in) {
237 X509error(ERR_R_SYS_LIB);
238 return 0;
239 }
240 inf = PEM_X509_INFO_read_bio(in, NULL, NULL, "");
241 BIO_free(in);
242 if (!inf) {
243 X509error(ERR_R_PEM_LIB);
244 return 0;
245 }
246 for (i = 0; i < sk_X509_INFO_num(inf); i++) {
247 itmp = sk_X509_INFO_value(inf, i);
248 if (itmp->x509) {
249 X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
250 count++;
251 }
252 if (itmp->crl) {
253 X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
254 count++;
255 }
256 }
257 if (count == 0)
258 X509error(X509_R_NO_CERTIFICATE_OR_CRL_FOUND);
259 sk_X509_INFO_pop_free(inf, X509_INFO_free);
260 return count;
261}
262LCRYPTO_ALIAS(X509_load_cert_crl_file);
diff --git a/src/lib/libcrypto/x509/by_mem.c b/src/lib/libcrypto/x509/by_mem.c
deleted file mode 100644
index 71afefa8a4..0000000000
--- a/src/lib/libcrypto/x509/by_mem.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/* $OpenBSD: by_mem.c,v 1.10 2024/08/31 10:19:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <sys/uio.h>
60#include <errno.h>
61#include <stdio.h>
62#include <time.h>
63#include <unistd.h>
64
65#include <openssl/buffer.h>
66#include <openssl/err.h>
67#include <openssl/pem.h>
68#include <openssl/lhash.h>
69#include <openssl/x509.h>
70
71#include "x509_local.h"
72
73static int by_mem_ctrl(X509_LOOKUP *, int, const char *, long, char **);
74
75static const X509_LOOKUP_METHOD x509_mem_lookup = {
76 .name = "Load cert from memory",
77 .new_item = NULL,
78 .free = NULL,
79 .ctrl = by_mem_ctrl,
80 .get_by_subject = NULL,
81};
82
83const X509_LOOKUP_METHOD *
84X509_LOOKUP_mem(void)
85{
86 return (&x509_mem_lookup);
87}
88LCRYPTO_ALIAS(X509_LOOKUP_mem);
89
90static int
91by_mem_ctrl(X509_LOOKUP *lu, int cmd, const char *buf,
92 long type, char **ret)
93{
94 STACK_OF(X509_INFO) *inf = NULL;
95 const struct iovec *iov;
96 X509_INFO *itmp;
97 BIO *in = NULL;
98 int i, count = 0, ok = 0;
99
100 iov = (const struct iovec *)buf;
101
102 if (!(cmd == X509_L_MEM && type == X509_FILETYPE_PEM))
103 goto done;
104
105 if ((in = BIO_new_mem_buf(iov->iov_base, iov->iov_len)) == NULL)
106 goto done;
107
108 if ((inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL)
109 goto done;
110
111 for (i = 0; i < sk_X509_INFO_num(inf); i++) {
112 itmp = sk_X509_INFO_value(inf, i);
113 if (itmp->x509) {
114 ok = X509_STORE_add_cert(lu->store_ctx, itmp->x509);
115 if (!ok)
116 goto done;
117 count++;
118 }
119 if (itmp->crl) {
120 ok = X509_STORE_add_crl(lu->store_ctx, itmp->crl);
121 if (!ok)
122 goto done;
123 count++;
124 }
125 }
126
127 ok = count != 0;
128 done:
129 if (count == 0)
130 X509error(ERR_R_PEM_LIB);
131 if (inf != NULL)
132 sk_X509_INFO_pop_free(inf, X509_INFO_free);
133 if (in != NULL)
134 BIO_free(in);
135 return (ok);
136}
diff --git a/src/lib/libcrypto/x509/x509.h b/src/lib/libcrypto/x509/x509.h
deleted file mode 100644
index a198b23202..0000000000
--- a/src/lib/libcrypto/x509/x509.h
+++ /dev/null
@@ -1,1041 +0,0 @@
1/* $OpenBSD: x509.h,v 1.121 2025/03/09 15:17:22 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * ECDH support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63
64#ifndef HEADER_X509_H
65#define HEADER_X509_H
66
67#include <openssl/opensslconf.h>
68
69#include <openssl/asn1.h>
70#ifndef OPENSSL_NO_BIO
71#include <openssl/bio.h>
72#endif
73#ifndef OPENSSL_NO_BUFFER
74#include <openssl/buffer.h>
75#endif
76#ifndef OPENSSL_NO_DH
77#include <openssl/dh.h>
78#endif
79#ifndef OPENSSL_NO_DSA
80#include <openssl/dsa.h>
81#endif
82#ifndef OPENSSL_NO_EC
83#include <openssl/ec.h>
84#endif
85#ifndef OPENSSL_NO_EVP
86#include <openssl/evp.h>
87#endif
88#ifndef OPENSSL_NO_RSA
89#include <openssl/rsa.h>
90#endif
91#ifndef OPENSSL_NO_SHA
92#include <openssl/sha.h>
93#endif
94#include <openssl/stack.h>
95#include <openssl/safestack.h>
96
97#include <openssl/ossl_typ.h>
98
99#ifdef __cplusplus
100extern "C" {
101#endif
102
103#define X509_FILETYPE_PEM 1
104#define X509_FILETYPE_ASN1 2
105#define X509_FILETYPE_DEFAULT 3
106
107#define X509v3_KU_DIGITAL_SIGNATURE 0x0080
108#define X509v3_KU_NON_REPUDIATION 0x0040
109#define X509v3_KU_KEY_ENCIPHERMENT 0x0020
110#define X509v3_KU_DATA_ENCIPHERMENT 0x0010
111#define X509v3_KU_KEY_AGREEMENT 0x0008
112#define X509v3_KU_KEY_CERT_SIGN 0x0004
113#define X509v3_KU_CRL_SIGN 0x0002
114#define X509v3_KU_ENCIPHER_ONLY 0x0001
115#define X509v3_KU_DECIPHER_ONLY 0x8000
116#define X509v3_KU_UNDEF 0xffff
117
118struct X509_algor_st {
119 ASN1_OBJECT *algorithm;
120 ASN1_TYPE *parameter;
121} /* X509_ALGOR */;
122
123typedef STACK_OF(X509_ALGOR) X509_ALGORS;
124
125typedef struct X509_val_st X509_VAL;
126
127typedef struct X509_sig_st X509_SIG;
128
129typedef struct X509_name_entry_st X509_NAME_ENTRY;
130
131DECLARE_STACK_OF(X509_NAME_ENTRY)
132
133DECLARE_STACK_OF(X509_NAME)
134
135typedef struct X509_extension_st X509_EXTENSION;
136
137typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
138
139DECLARE_STACK_OF(X509_EXTENSION)
140
141typedef struct x509_attributes_st X509_ATTRIBUTE;
142
143DECLARE_STACK_OF(X509_ATTRIBUTE)
144
145typedef struct X509_req_info_st X509_REQ_INFO;
146
147typedef struct X509_req_st X509_REQ;
148
149typedef struct x509_cinf_st X509_CINF;
150
151DECLARE_STACK_OF(X509)
152
153#define X509_TRUST_COMPAT 1
154#define X509_TRUST_SSL_CLIENT 2
155#define X509_TRUST_SSL_SERVER 3
156#define X509_TRUST_EMAIL 4
157#define X509_TRUST_OBJECT_SIGN 5
158#define X509_TRUST_OCSP_SIGN 6
159#define X509_TRUST_OCSP_REQUEST 7
160#define X509_TRUST_TSA 8
161
162/* Keep these up to date! */
163#define X509_TRUST_MIN 1
164#define X509_TRUST_MAX 8
165
166/* Flags for X509_print_ex() */
167
168#define X509_FLAG_COMPAT 0
169#define X509_FLAG_NO_HEADER 1L
170#define X509_FLAG_NO_VERSION (1L << 1)
171#define X509_FLAG_NO_SERIAL (1L << 2)
172#define X509_FLAG_NO_SIGNAME (1L << 3)
173#define X509_FLAG_NO_ISSUER (1L << 4)
174#define X509_FLAG_NO_VALIDITY (1L << 5)
175#define X509_FLAG_NO_SUBJECT (1L << 6)
176#define X509_FLAG_NO_PUBKEY (1L << 7)
177#define X509_FLAG_NO_EXTENSIONS (1L << 8)
178#define X509_FLAG_NO_SIGDUMP (1L << 9)
179#define X509_FLAG_NO_AUX (1L << 10)
180#define X509_FLAG_NO_ATTRIBUTES (1L << 11)
181
182/* Flags specific to X509_NAME_print_ex() */
183
184/* The field separator information */
185
186#define XN_FLAG_SEP_MASK (0xf << 16)
187
188#define XN_FLAG_COMPAT 0 /* Traditional SSLeay: use old X509_NAME_print */
189#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) /* RFC2253 ,+ */
190#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) /* ,+ spaced: more readable */
191#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) /* ;+ spaced */
192#define XN_FLAG_SEP_MULTILINE (4 << 16) /* One line per field */
193
194#define XN_FLAG_DN_REV (1 << 20) /* Reverse DN order */
195
196/* How the field name is shown */
197
198#define XN_FLAG_FN_MASK (0x3 << 21)
199
200#define XN_FLAG_FN_SN 0 /* Object short name */
201#define XN_FLAG_FN_LN (1 << 21) /* Object long name */
202#define XN_FLAG_FN_OID (2 << 21) /* Always use OIDs */
203#define XN_FLAG_FN_NONE (3 << 21) /* No field names */
204
205#define XN_FLAG_SPC_EQ (1 << 23) /* Put spaces round '=' */
206
207/* This determines if we dump fields we don't recognise:
208 * RFC2253 requires this.
209 */
210
211#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
212
213#define XN_FLAG_FN_ALIGN (1 << 25) /* Align field names to 20 characters */
214
215/* Complete set of RFC2253 flags */
216
217#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
218 XN_FLAG_SEP_COMMA_PLUS | \
219 XN_FLAG_DN_REV | \
220 XN_FLAG_FN_SN | \
221 XN_FLAG_DUMP_UNKNOWN_FIELDS)
222
223/* readable oneline form */
224
225#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
226 ASN1_STRFLGS_ESC_QUOTE | \
227 XN_FLAG_SEP_CPLUS_SPC | \
228 XN_FLAG_SPC_EQ | \
229 XN_FLAG_FN_SN)
230
231/* readable multiline form */
232
233#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
234 ASN1_STRFLGS_ESC_MSB | \
235 XN_FLAG_SEP_MULTILINE | \
236 XN_FLAG_SPC_EQ | \
237 XN_FLAG_FN_LN | \
238 XN_FLAG_FN_ALIGN)
239
240DECLARE_STACK_OF(X509_REVOKED)
241
242typedef struct X509_crl_info_st X509_CRL_INFO;
243
244DECLARE_STACK_OF(X509_CRL)
245
246typedef struct private_key_st {
247 int version;
248 /* The PKCS#8 data types */
249 X509_ALGOR *enc_algor;
250 ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
251
252 /* When decrypted, the following will not be NULL */
253 EVP_PKEY *dec_pkey;
254
255 /* used to encrypt and decrypt */
256 int key_length;
257 char *key_data;
258 int key_free; /* true if we should auto free key_data */
259
260 /* expanded version of 'enc_algor' */
261 EVP_CIPHER_INFO cipher;
262
263 int references;
264} X509_PKEY;
265
266#ifndef OPENSSL_NO_EVP
267typedef struct X509_info_st {
268 X509 *x509;
269 X509_CRL *crl;
270 X509_PKEY *x_pkey;
271
272 EVP_CIPHER_INFO enc_cipher;
273 int enc_len;
274 char *enc_data;
275
276 int references;
277} X509_INFO;
278
279DECLARE_STACK_OF(X509_INFO)
280#endif
281
282/* The next 2 structures and their 8 routines were sent to me by
283 * Pat Richard <patr@x509.com> and are used to manipulate
284 * Netscapes spki structures - useful if you are writing a CA web page
285 */
286typedef struct Netscape_spkac_st {
287 X509_PUBKEY *pubkey;
288 ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */
289} NETSCAPE_SPKAC;
290
291typedef struct Netscape_spki_st {
292 NETSCAPE_SPKAC *spkac; /* signed public key and challenge */
293 X509_ALGOR *sig_algor;
294 ASN1_BIT_STRING *signature;
295} NETSCAPE_SPKI;
296
297typedef struct PBEPARAM_st {
298 ASN1_OCTET_STRING *salt;
299 ASN1_INTEGER *iter;
300} PBEPARAM;
301
302#ifdef __cplusplus
303}
304#endif
305
306#include <openssl/x509_vfy.h>
307#include <openssl/pkcs7.h>
308
309#ifdef __cplusplus
310extern "C" {
311#endif
312
313#define X509_extract_key(x) X509_get_pubkey(x) /*****/
314#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
315#define X509_name_cmp(a,b) X509_NAME_cmp((a),(b))
316
317int X509_CRL_up_ref(X509_CRL *x);
318int X509_CRL_get_signature_nid(const X509_CRL *crl);
319
320int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp);
321
322const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl);
323long X509_CRL_get_version(const X509_CRL *crl);
324const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl);
325const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl);
326ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl);
327ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl);
328X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl);
329STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl);
330void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
331 const X509_ALGOR **palg);
332
333const X509_ALGOR *X509_CRL_get0_tbs_sigalg(const X509_CRL *crl);
334
335int X509_REQ_get_signature_nid(const X509_REQ *req);
336
337void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
338 const X509_ALGOR **palg);
339
340X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x);
341
342const char *X509_verify_cert_error_string(long n);
343
344#ifndef OPENSSL_NO_EVP
345int X509_verify(X509 *a, EVP_PKEY *r);
346
347int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
348int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
349int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
350
351NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len);
352char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
353EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
354int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
355
356int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
357
358int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
359int X509_signature_print(BIO *bp, const X509_ALGOR *alg,
360 const ASN1_STRING *sig);
361
362int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
363int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
364int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
365int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
366int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
367int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
368int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
369
370int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
371 unsigned char *md, unsigned int *len);
372int X509_digest(const X509 *data,const EVP_MD *type,
373 unsigned char *md, unsigned int *len);
374int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
375 unsigned char *md, unsigned int *len);
376int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type,
377 unsigned char *md, unsigned int *len);
378int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type,
379 unsigned char *md, unsigned int *len);
380#endif
381
382X509 *d2i_X509_fp(FILE *fp, X509 **x509);
383int i2d_X509_fp(FILE *fp,X509 *x509);
384X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl);
385int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl);
386X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req);
387int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req);
388#ifndef OPENSSL_NO_RSA
389RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa);
390int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa);
391RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
392int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
393RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa);
394int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa);
395#endif
396#ifndef OPENSSL_NO_DSA
397DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
398int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
399DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
400int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
401#endif
402#ifndef OPENSSL_NO_EC
403EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
404int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
405EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
406int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
407#endif
408X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
409int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8);
410PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
411 PKCS8_PRIV_KEY_INFO **p8inf);
412int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
413int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
414int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
415EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
416int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
417EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
418
419#ifndef OPENSSL_NO_BIO
420X509 *d2i_X509_bio(BIO *bp,X509 **x509);
421int i2d_X509_bio(BIO *bp,X509 *x509);
422X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl);
423int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl);
424X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req);
425int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req);
426#ifndef OPENSSL_NO_RSA
427RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa);
428int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa);
429RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
430int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
431RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa);
432int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa);
433#endif
434#ifndef OPENSSL_NO_DSA
435DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
436int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
437DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
438int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
439#endif
440#ifndef OPENSSL_NO_EC
441EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
442int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
443EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
444int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
445#endif
446X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8);
447int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8);
448PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
449 PKCS8_PRIV_KEY_INFO **p8inf);
450int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
451int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
452int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
453EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
454int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
455EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
456#endif
457
458X509 *X509_dup(X509 *x509);
459X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
460X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
461X509_CRL *X509_CRL_dup(X509_CRL *crl);
462X509_REQ *X509_REQ_dup(X509_REQ *req);
463X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
464int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval);
465void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, const void **ppval,
466 const X509_ALGOR *algor);
467int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
468
469X509_NAME *X509_NAME_dup(X509_NAME *xn);
470int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, size_t *pderlen);
471X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
472
473int X509_cmp_time(const ASN1_TIME *s, time_t *t);
474int X509_cmp_current_time(const ASN1_TIME *s);
475ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
476ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s,
477 int offset_day, long offset_sec, time_t *t);
478ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj);
479
480const char * X509_get_default_cert_area(void );
481const char * X509_get_default_cert_dir(void );
482const char * X509_get_default_cert_file(void );
483const char * X509_get_default_cert_dir_env(void );
484const char * X509_get_default_cert_file_env(void );
485const char * X509_get_default_private_dir(void );
486
487X509_REQ * X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
488X509 * X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey);
489
490X509_ALGOR *X509_ALGOR_new(void);
491void X509_ALGOR_free(X509_ALGOR *a);
492X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **a, const unsigned char **in, long len);
493int i2d_X509_ALGOR(X509_ALGOR *a, unsigned char **out);
494extern const ASN1_ITEM X509_ALGOR_it;
495X509_ALGORS *d2i_X509_ALGORS(X509_ALGORS **a, const unsigned char **in, long len);
496int i2d_X509_ALGORS(X509_ALGORS *a, unsigned char **out);
497extern const ASN1_ITEM X509_ALGORS_it;
498X509_VAL *X509_VAL_new(void);
499void X509_VAL_free(X509_VAL *a);
500X509_VAL *d2i_X509_VAL(X509_VAL **a, const unsigned char **in, long len);
501int i2d_X509_VAL(X509_VAL *a, unsigned char **out);
502extern const ASN1_ITEM X509_VAL_it;
503
504X509_PUBKEY *X509_PUBKEY_new(void);
505void X509_PUBKEY_free(X509_PUBKEY *a);
506X509_PUBKEY *d2i_X509_PUBKEY(X509_PUBKEY **a, const unsigned char **in, long len);
507int i2d_X509_PUBKEY(X509_PUBKEY *a, unsigned char **out);
508extern const ASN1_ITEM X509_PUBKEY_it;
509
510int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
511EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key);
512EVP_PKEY * X509_PUBKEY_get0(X509_PUBKEY *key);
513int X509_get_pubkey_parameters(EVP_PKEY *pkey,
514 STACK_OF(X509) *chain);
515int i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp);
516EVP_PKEY * d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp,
517 long length);
518#ifndef OPENSSL_NO_RSA
519int i2d_RSA_PUBKEY(RSA *a,unsigned char **pp);
520RSA * d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp,
521 long length);
522#endif
523#ifndef OPENSSL_NO_DSA
524int i2d_DSA_PUBKEY(DSA *a,unsigned char **pp);
525DSA * d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp,
526 long length);
527#endif
528#ifndef OPENSSL_NO_EC
529int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
530EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp,
531 long length);
532#endif
533
534X509_SIG *X509_SIG_new(void);
535void X509_SIG_free(X509_SIG *a);
536X509_SIG *d2i_X509_SIG(X509_SIG **a, const unsigned char **in, long len);
537int i2d_X509_SIG(X509_SIG *a, unsigned char **out);
538extern const ASN1_ITEM X509_SIG_it;
539void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
540 const ASN1_OCTET_STRING **pdigest);
541void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg,
542 ASN1_OCTET_STRING **pdigest);
543
544X509_REQ_INFO *X509_REQ_INFO_new(void);
545void X509_REQ_INFO_free(X509_REQ_INFO *a);
546X509_REQ_INFO *d2i_X509_REQ_INFO(X509_REQ_INFO **a, const unsigned char **in, long len);
547int i2d_X509_REQ_INFO(X509_REQ_INFO *a, unsigned char **out);
548extern const ASN1_ITEM X509_REQ_INFO_it;
549X509_REQ *X509_REQ_new(void);
550void X509_REQ_free(X509_REQ *a);
551X509_REQ *d2i_X509_REQ(X509_REQ **a, const unsigned char **in, long len);
552int i2d_X509_REQ(X509_REQ *a, unsigned char **out);
553extern const ASN1_ITEM X509_REQ_it;
554
555X509_ATTRIBUTE *X509_ATTRIBUTE_new(void);
556void X509_ATTRIBUTE_free(X509_ATTRIBUTE *a);
557X509_ATTRIBUTE *d2i_X509_ATTRIBUTE(X509_ATTRIBUTE **a, const unsigned char **in, long len);
558int i2d_X509_ATTRIBUTE(X509_ATTRIBUTE *a, unsigned char **out);
559extern const ASN1_ITEM X509_ATTRIBUTE_it;
560X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
561
562X509_EXTENSION *X509_EXTENSION_new(void);
563void X509_EXTENSION_free(X509_EXTENSION *a);
564X509_EXTENSION *d2i_X509_EXTENSION(X509_EXTENSION **a, const unsigned char **in, long len);
565int i2d_X509_EXTENSION(X509_EXTENSION *a, unsigned char **out);
566extern const ASN1_ITEM X509_EXTENSION_it;
567X509_EXTENSIONS *d2i_X509_EXTENSIONS(X509_EXTENSIONS **a, const unsigned char **in, long len);
568int i2d_X509_EXTENSIONS(X509_EXTENSIONS *a, unsigned char **out);
569extern const ASN1_ITEM X509_EXTENSIONS_it;
570
571X509_NAME_ENTRY *X509_NAME_ENTRY_new(void);
572void X509_NAME_ENTRY_free(X509_NAME_ENTRY *a);
573X509_NAME_ENTRY *d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, const unsigned char **in, long len);
574int i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **out);
575extern const ASN1_ITEM X509_NAME_ENTRY_it;
576
577X509_NAME *X509_NAME_new(void);
578void X509_NAME_free(X509_NAME *a);
579X509_NAME *d2i_X509_NAME(X509_NAME **a, const unsigned char **in, long len);
580int i2d_X509_NAME(X509_NAME *a, unsigned char **out);
581extern const ASN1_ITEM X509_NAME_it;
582
583int X509_NAME_set(X509_NAME **xn, X509_NAME *name);
584
585X509_CINF *X509_CINF_new(void);
586void X509_CINF_free(X509_CINF *a);
587X509_CINF *d2i_X509_CINF(X509_CINF **a, const unsigned char **in, long len);
588int i2d_X509_CINF(X509_CINF *a, unsigned char **out);
589extern const ASN1_ITEM X509_CINF_it;
590
591X509 *X509_new(void);
592void X509_free(X509 *a);
593X509 *d2i_X509(X509 **a, const unsigned char **in, long len);
594int i2d_X509(X509 *a, unsigned char **out);
595extern const ASN1_ITEM X509_it;
596
597int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
598 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
599int X509_set_ex_data(X509 *r, int idx, void *arg);
600void *X509_get_ex_data(X509 *r, int idx);
601int i2d_X509_AUX(X509 *a,unsigned char **pp);
602X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length);
603
604int i2d_re_X509_tbs(X509 *x, unsigned char **pp);
605
606/* Flags returned by X509_get_signature_info(): valid and suitable for TLS. */
607#define X509_SIG_INFO_VALID 1
608#define X509_SIG_INFO_TLS 2
609int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
610 uint32_t *flags);
611
612void X509_get0_signature(const ASN1_BIT_STRING **psig,
613 const X509_ALGOR **palg, const X509 *x);
614int X509_get_signature_nid(const X509 *x);
615
616int X509_alias_set1(X509 *x, const unsigned char *name, int len);
617int X509_keyid_set1(X509 *x, const unsigned char *id, int len);
618unsigned char *X509_alias_get0(X509 *x, int *len);
619unsigned char *X509_keyid_get0(X509 *x, int *len);
620int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj);
621int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj);
622void X509_trust_clear(X509 *x);
623void X509_reject_clear(X509 *x);
624
625X509_REVOKED *X509_REVOKED_new(void);
626void X509_REVOKED_free(X509_REVOKED *a);
627X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *a);
628X509_REVOKED *d2i_X509_REVOKED(X509_REVOKED **a, const unsigned char **in, long len);
629int i2d_X509_REVOKED(X509_REVOKED *a, unsigned char **out);
630extern const ASN1_ITEM X509_REVOKED_it;
631
632X509_CRL_INFO *X509_CRL_INFO_new(void);
633void X509_CRL_INFO_free(X509_CRL_INFO *a);
634X509_CRL_INFO *d2i_X509_CRL_INFO(X509_CRL_INFO **a, const unsigned char **in, long len);
635int i2d_X509_CRL_INFO(X509_CRL_INFO *a, unsigned char **out);
636extern const ASN1_ITEM X509_CRL_INFO_it;
637
638X509_CRL *X509_CRL_new(void);
639void X509_CRL_free(X509_CRL *a);
640X509_CRL *d2i_X509_CRL(X509_CRL **a, const unsigned char **in, long len);
641int i2d_X509_CRL(X509_CRL *a, unsigned char **out);
642extern const ASN1_ITEM X509_CRL_it;
643
644int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
645int X509_CRL_get0_by_serial(X509_CRL *crl,
646 X509_REVOKED **ret, ASN1_INTEGER *serial);
647int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
648
649X509_PKEY * X509_PKEY_new(void );
650void X509_PKEY_free(X509_PKEY *a);
651
652NETSCAPE_SPKI *NETSCAPE_SPKI_new(void);
653void NETSCAPE_SPKI_free(NETSCAPE_SPKI *a);
654NETSCAPE_SPKI *d2i_NETSCAPE_SPKI(NETSCAPE_SPKI **a, const unsigned char **in, long len);
655int i2d_NETSCAPE_SPKI(NETSCAPE_SPKI *a, unsigned char **out);
656extern const ASN1_ITEM NETSCAPE_SPKI_it;
657NETSCAPE_SPKAC *NETSCAPE_SPKAC_new(void);
658void NETSCAPE_SPKAC_free(NETSCAPE_SPKAC *a);
659NETSCAPE_SPKAC *d2i_NETSCAPE_SPKAC(NETSCAPE_SPKAC **a, const unsigned char **in, long len);
660int i2d_NETSCAPE_SPKAC(NETSCAPE_SPKAC *a, unsigned char **out);
661extern const ASN1_ITEM NETSCAPE_SPKAC_it;
662
663#ifndef OPENSSL_NO_EVP
664X509_INFO * X509_INFO_new(void);
665void X509_INFO_free(X509_INFO *a);
666char * X509_NAME_oneline(const X509_NAME *a, char *buf, int size);
667
668int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data,
669 unsigned char *md,unsigned int *len);
670
671int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
672 ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey);
673
674int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
675 ASN1_BIT_STRING *signature,
676 void *data, EVP_PKEY *pkey, const EVP_MD *type);
677int ASN1_item_sign_ctx(const ASN1_ITEM *it,
678 X509_ALGOR *algor1, X509_ALGOR *algor2,
679 ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx);
680#endif
681
682const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x);
683void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **issuerUID,
684 const ASN1_BIT_STRING **subjectUID);
685const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x);
686int X509_set_version(X509 *x, long version);
687long X509_get_version(const X509 *x);
688int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
689ASN1_INTEGER * X509_get_serialNumber(X509 *x);
690const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x);
691int X509_set_issuer_name(X509 *x, X509_NAME *name);
692X509_NAME * X509_get_issuer_name(const X509 *a);
693int X509_set_subject_name(X509 *x, X509_NAME *name);
694X509_NAME * X509_get_subject_name(const X509 *a);
695int X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
696int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm);
697int X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
698int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm);
699const ASN1_TIME *X509_get0_notBefore(const X509 *x);
700ASN1_TIME *X509_getm_notBefore(const X509 *x);
701const ASN1_TIME *X509_get0_notAfter(const X509 *x);
702ASN1_TIME *X509_getm_notAfter(const X509 *x);
703int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
704EVP_PKEY * X509_get_pubkey(X509 *x);
705EVP_PKEY * X509_get0_pubkey(const X509 *x);
706ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);
707int X509_certificate_type(const X509 *x, const EVP_PKEY *pubkey);
708int X509_get_signature_type(const X509 *x);
709
710#define X509_get_notBefore X509_getm_notBefore
711#define X509_get_notAfter X509_getm_notAfter
712
713int X509_REQ_set_version(X509_REQ *x,long version);
714long X509_REQ_get_version(const X509_REQ *x);
715int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
716X509_NAME *X509_REQ_get_subject_name(const X509_REQ *x);
717int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
718EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *req);
719int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp);
720EVP_PKEY * X509_REQ_get0_pubkey(X509_REQ *req);
721int X509_REQ_extension_nid(int nid);
722STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
723int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
724 int nid);
725int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
726int X509_REQ_get_attr_count(const X509_REQ *req);
727int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
728 int lastpos);
729int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
730 int lastpos);
731X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
732X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
733int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
734int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
735 const ASN1_OBJECT *obj, int type,
736 const unsigned char *bytes, int len);
737int X509_REQ_add1_attr_by_NID(X509_REQ *req,
738 int nid, int type,
739 const unsigned char *bytes, int len);
740int X509_REQ_add1_attr_by_txt(X509_REQ *req,
741 const char *attrname, int type,
742 const unsigned char *bytes, int len);
743
744int X509_CRL_set_version(X509_CRL *x, long version);
745int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
746int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
747int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
748int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
749int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
750int X509_CRL_sort(X509_CRL *crl);
751
752const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *x);
753const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x);
754const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x);
755int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
756int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
757
758int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey);
759
760int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey);
761
762int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
763unsigned long X509_issuer_and_serial_hash(X509 *a);
764
765int X509_issuer_name_cmp(const X509 *a, const X509 *b);
766unsigned long X509_issuer_name_hash(X509 *a);
767
768int X509_subject_name_cmp(const X509 *a, const X509 *b);
769unsigned long X509_subject_name_hash(X509 *x);
770
771#ifndef OPENSSL_NO_MD5
772unsigned long X509_issuer_name_hash_old(X509 *a);
773unsigned long X509_subject_name_hash_old(X509 *x);
774#endif
775
776int X509_cmp(const X509 *a, const X509 *b);
777int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
778unsigned long X509_NAME_hash(X509_NAME *x);
779unsigned long X509_NAME_hash_old(X509_NAME *x);
780
781int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
782int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
783int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
784int X509_print_fp(FILE *bp,X509 *x);
785int X509_CRL_print_fp(FILE *bp,X509_CRL *x);
786int X509_REQ_print_fp(FILE *bp,X509_REQ *req);
787int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent,
788 unsigned long flags);
789
790#ifndef OPENSSL_NO_BIO
791int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
792 unsigned long flags);
793int X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
794int X509_print(BIO *bp,X509 *x);
795int X509_ocspid_print(BIO *bp,X509 *x);
796int X509_CRL_print(BIO *bp,X509_CRL *x);
797int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag);
798int X509_REQ_print(BIO *bp,X509_REQ *req);
799#endif
800
801int X509_NAME_entry_count(const X509_NAME *name);
802int X509_NAME_get_text_by_NID(X509_NAME *name, int nid,
803 char *buf,int len);
804int X509_NAME_get_text_by_OBJ(X509_NAME *name,
805 const ASN1_OBJECT *obj, char *buf,int len);
806
807/* NOTE: you should be passing -1, not 0 as lastpos. The functions that use
808 * lastpos, search after that position on. */
809int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid,
810 int lastpos);
811int X509_NAME_get_index_by_OBJ(const X509_NAME *name,
812 const ASN1_OBJECT *obj, int lastpos);
813X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc);
814X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
815int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne,
816 int loc, int set);
817int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
818 int type, const unsigned char *bytes, int len, int loc, int set);
819int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
820 const unsigned char *bytes, int len, int loc, int set);
821X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
822 const char *field, int type, const unsigned char *bytes, int len);
823X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
824 int type, const unsigned char *bytes, int len);
825int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
826 const unsigned char *bytes, int len, int loc, int set);
827X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
828 const ASN1_OBJECT *obj, int type,
829 const unsigned char *bytes, int len);
830int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne,
831 const ASN1_OBJECT *obj);
832int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
833 const unsigned char *bytes, int len);
834ASN1_OBJECT * X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne);
835ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne);
836int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne);
837
838int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
839int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
840 int nid, int lastpos);
841int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
842 const ASN1_OBJECT *obj, int lastpos);
843int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
844 int crit, int lastpos);
845X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
846X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
847STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
848 X509_EXTENSION *ex, int loc);
849
850int X509_get_ext_count(const X509 *x);
851int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos);
852int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj,
853 int lastpos);
854int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos);
855X509_EXTENSION *X509_get_ext(const X509 *x, int loc);
856X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
857int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
858void * X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx);
859int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
860 unsigned long flags);
861
862int X509_CRL_get_ext_count(const X509_CRL *x);
863int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid,
864 int lastpos);
865int X509_CRL_get_ext_by_OBJ(const X509_CRL *x,
866 const ASN1_OBJECT *obj, int lastpos);
867int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit,
868 int lastpos);
869X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc);
870X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
871int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
872void * X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit,
873 int *idx);
874int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value,
875 int crit, unsigned long flags);
876
877int X509_REVOKED_get_ext_count(const X509_REVOKED *x);
878int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid,
879 int lastpos);
880int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x,
881 const ASN1_OBJECT *obj, int lastpos);
882int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x,
883 int crit, int lastpos);
884X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc);
885X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
886int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex,
887 int loc);
888void * X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid,
889 int *crit, int *idx);
890int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value,
891 int crit, unsigned long flags);
892
893X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
894 int nid, int crit, ASN1_OCTET_STRING *data);
895X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
896 const ASN1_OBJECT *obj, int crit, ASN1_OCTET_STRING *data);
897int X509_EXTENSION_set_object(X509_EXTENSION *ex,
898 const ASN1_OBJECT *obj);
899int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
900int X509_EXTENSION_set_data(X509_EXTENSION *ex,
901 ASN1_OCTET_STRING *data);
902ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex);
903ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
904int X509_EXTENSION_get_critical(const X509_EXTENSION *ex);
905
906X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
907 int atrtype, const void *data, int len);
908X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
909 const ASN1_OBJECT *obj, int atrtype, const void *data, int len);
910X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
911 const char *atrname, int type, const unsigned char *bytes, int len);
912int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
913int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len);
914void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
915 int atrtype, void *data);
916int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr);
917ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
918ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
919
920int X509_verify_cert(X509_STORE_CTX *ctx);
921
922/* lookup a cert from a X509 STACK */
923X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name,
924 ASN1_INTEGER *serial);
925X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name);
926
927extern const ASN1_ITEM PBEPARAM_it;
928
929/* PKCS#8 utilities */
930
931PKCS8_PRIV_KEY_INFO *PKCS8_PRIV_KEY_INFO_new(void);
932void PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *a);
933PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a, const unsigned char **in, long len);
934int i2d_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO *a, unsigned char **out);
935extern const ASN1_ITEM PKCS8_PRIV_KEY_INFO_it;
936
937EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8);
938PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
939
940int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version,
941 int ptype, void *pval, unsigned char *penc, int penclen);
942int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, const unsigned char **pk,
943 int *ppklen, const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8);
944
945const STACK_OF(X509_ATTRIBUTE) *PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8);
946int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type,
947 const unsigned char *bytes, int len);
948
949int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int ptype,
950 void *pval, unsigned char *penc, int penclen);
951int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk,
952 int *ppklen, X509_ALGOR **pa, X509_PUBKEY *pub);
953
954int X509_up_ref(X509 *x);
955STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);
956
957void ERR_load_X509_strings(void);
958
959/* Error codes for the X509 functions. */
960
961/* Function codes. */
962#define X509_F_ADD_CERT_DIR 100
963#define X509_F_BY_FILE_CTRL 101
964#define X509_F_CHECK_POLICY 145
965#define X509_F_DIR_CTRL 102
966#define X509_F_GET_CERT_BY_SUBJECT 103
967#define X509_F_NETSCAPE_SPKI_B64_DECODE 129
968#define X509_F_NETSCAPE_SPKI_B64_ENCODE 130
969#define X509_F_X509AT_ADD1_ATTR 135
970#define X509_F_X509V3_ADD_EXT 104
971#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136
972#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137
973#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140
974#define X509_F_X509_ATTRIBUTE_GET0_DATA 139
975#define X509_F_X509_ATTRIBUTE_SET1_DATA 138
976#define X509_F_X509_CHECK_PRIVATE_KEY 128
977#define X509_F_X509_CRL_PRINT_FP 147
978#define X509_F_X509_EXTENSION_CREATE_BY_NID 108
979#define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109
980#define X509_F_X509_GET_PUBKEY_PARAMETERS 110
981#define X509_F_X509_LOAD_CERT_CRL_FILE 132
982#define X509_F_X509_LOAD_CERT_FILE 111
983#define X509_F_X509_LOAD_CRL_FILE 112
984#define X509_F_X509_NAME_ADD_ENTRY 113
985#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114
986#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131
987#define X509_F_X509_NAME_ENTRY_SET_OBJECT 115
988#define X509_F_X509_NAME_ONELINE 116
989#define X509_F_X509_NAME_PRINT 117
990#define X509_F_X509_PRINT_EX_FP 118
991#define X509_F_X509_PUBKEY_GET 119
992#define X509_F_X509_PUBKEY_SET 120
993#define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144
994#define X509_F_X509_REQ_PRINT_EX 121
995#define X509_F_X509_REQ_PRINT_FP 122
996#define X509_F_X509_REQ_TO_X509 123
997#define X509_F_X509_STORE_ADD_CERT 124
998#define X509_F_X509_STORE_ADD_CRL 125
999#define X509_F_X509_STORE_CTX_GET1_ISSUER 146
1000#define X509_F_X509_STORE_CTX_INIT 143
1001#define X509_F_X509_STORE_CTX_NEW 142
1002#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134
1003#define X509_F_X509_TO_X509_REQ 126
1004#define X509_F_X509_TRUST_ADD 133
1005#define X509_F_X509_TRUST_SET 141
1006#define X509_F_X509_VERIFY_CERT 127
1007
1008/* Reason codes. */
1009#define X509_R_BAD_X509_FILETYPE 100
1010#define X509_R_BASE64_DECODE_ERROR 118
1011#define X509_R_CANT_CHECK_DH_KEY 114
1012#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101
1013#define X509_R_ERR_ASN1_LIB 102
1014#define X509_R_INVALID_DIRECTORY 113
1015#define X509_R_INVALID_FIELD_NAME 119
1016#define X509_R_INVALID_TRUST 123
1017#define X509_R_INVALID_VERSION 137
1018#define X509_R_KEY_TYPE_MISMATCH 115
1019#define X509_R_KEY_VALUES_MISMATCH 116
1020#define X509_R_LOADING_CERT_DIR 103
1021#define X509_R_LOADING_DEFAULTS 104
1022#define X509_R_METHOD_NOT_SUPPORTED 124
1023#define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 136
1024#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105
1025#define X509_R_PUBLIC_KEY_DECODE_ERROR 125
1026#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126
1027#define X509_R_SHOULD_RETRY 106
1028#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107
1029#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108
1030#define X509_R_UNKNOWN_KEY_TYPE 117
1031#define X509_R_UNKNOWN_NID 109
1032#define X509_R_UNKNOWN_PURPOSE_ID 121
1033#define X509_R_UNKNOWN_TRUST_ID 120
1034#define X509_R_UNSUPPORTED_ALGORITHM 111
1035#define X509_R_WRONG_LOOKUP_TYPE 112
1036#define X509_R_WRONG_TYPE 122
1037
1038#ifdef __cplusplus
1039}
1040#endif
1041#endif
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c
deleted file mode 100644
index 2208cc434e..0000000000
--- a/src/lib/libcrypto/x509/x509_addr.c
+++ /dev/null
@@ -1,2074 +0,0 @@
1/* $OpenBSD: x509_addr.c,v 1.93 2024/07/13 15:08:58 tb Exp $ */
2/*
3 * Contributed to the OpenSSL Project by the American Registry for
4 * Internet Numbers ("ARIN").
5 */
6/* ====================================================================
7 * Copyright (c) 2006-2016 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 */
58
59/*
60 * Implementation of RFC 3779 section 2.2.
61 */
62
63#include <limits.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67
68#include <openssl/asn1.h>
69#include <openssl/asn1t.h>
70#include <openssl/buffer.h>
71#include <openssl/conf.h>
72#include <openssl/err.h>
73#include <openssl/x509.h>
74#include <openssl/x509v3.h>
75
76#include "asn1_local.h"
77#include "bytestring.h"
78#include "x509_local.h"
79
80#ifndef OPENSSL_NO_RFC3779
81
82/*
83 * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
84 */
85
86static const ASN1_TEMPLATE IPAddressRange_seq_tt[] = {
87 {
88 .flags = 0,
89 .tag = 0,
90 .offset = offsetof(IPAddressRange, min),
91 .field_name = "min",
92 .item = &ASN1_BIT_STRING_it,
93 },
94 {
95 .flags = 0,
96 .tag = 0,
97 .offset = offsetof(IPAddressRange, max),
98 .field_name = "max",
99 .item = &ASN1_BIT_STRING_it,
100 },
101};
102
103const ASN1_ITEM IPAddressRange_it = {
104 .itype = ASN1_ITYPE_SEQUENCE,
105 .utype = V_ASN1_SEQUENCE,
106 .templates = IPAddressRange_seq_tt,
107 .tcount = sizeof(IPAddressRange_seq_tt) / sizeof(ASN1_TEMPLATE),
108 .funcs = NULL,
109 .size = sizeof(IPAddressRange),
110 .sname = "IPAddressRange",
111};
112LCRYPTO_ALIAS(IPAddressRange_it);
113
114static const ASN1_TEMPLATE IPAddressOrRange_ch_tt[] = {
115 {
116 .flags = 0,
117 .tag = 0,
118 .offset = offsetof(IPAddressOrRange, u.addressPrefix),
119 .field_name = "u.addressPrefix",
120 .item = &ASN1_BIT_STRING_it,
121 },
122 {
123 .flags = 0,
124 .tag = 0,
125 .offset = offsetof(IPAddressOrRange, u.addressRange),
126 .field_name = "u.addressRange",
127 .item = &IPAddressRange_it,
128 },
129};
130
131const ASN1_ITEM IPAddressOrRange_it = {
132 .itype = ASN1_ITYPE_CHOICE,
133 .utype = offsetof(IPAddressOrRange, type),
134 .templates = IPAddressOrRange_ch_tt,
135 .tcount = sizeof(IPAddressOrRange_ch_tt) / sizeof(ASN1_TEMPLATE),
136 .funcs = NULL,
137 .size = sizeof(IPAddressOrRange),
138 .sname = "IPAddressOrRange",
139};
140LCRYPTO_ALIAS(IPAddressOrRange_it);
141
142static const ASN1_TEMPLATE IPAddressChoice_ch_tt[] = {
143 {
144 .flags = 0,
145 .tag = 0,
146 .offset = offsetof(IPAddressChoice, u.inherit),
147 .field_name = "u.inherit",
148 .item = &ASN1_NULL_it,
149 },
150 {
151 .flags = ASN1_TFLG_SEQUENCE_OF,
152 .tag = 0,
153 .offset = offsetof(IPAddressChoice, u.addressesOrRanges),
154 .field_name = "u.addressesOrRanges",
155 .item = &IPAddressOrRange_it,
156 },
157};
158
159const ASN1_ITEM IPAddressChoice_it = {
160 .itype = ASN1_ITYPE_CHOICE,
161 .utype = offsetof(IPAddressChoice, type),
162 .templates = IPAddressChoice_ch_tt,
163 .tcount = sizeof(IPAddressChoice_ch_tt) / sizeof(ASN1_TEMPLATE),
164 .funcs = NULL,
165 .size = sizeof(IPAddressChoice),
166 .sname = "IPAddressChoice",
167};
168LCRYPTO_ALIAS(IPAddressChoice_it);
169
170static const ASN1_TEMPLATE IPAddressFamily_seq_tt[] = {
171 {
172 .flags = 0,
173 .tag = 0,
174 .offset = offsetof(IPAddressFamily, addressFamily),
175 .field_name = "addressFamily",
176 .item = &ASN1_OCTET_STRING_it,
177 },
178 {
179 .flags = 0,
180 .tag = 0,
181 .offset = offsetof(IPAddressFamily, ipAddressChoice),
182 .field_name = "ipAddressChoice",
183 .item = &IPAddressChoice_it,
184 },
185};
186
187const ASN1_ITEM IPAddressFamily_it = {
188 .itype = ASN1_ITYPE_SEQUENCE,
189 .utype = V_ASN1_SEQUENCE,
190 .templates = IPAddressFamily_seq_tt,
191 .tcount = sizeof(IPAddressFamily_seq_tt) / sizeof(ASN1_TEMPLATE),
192 .funcs = NULL,
193 .size = sizeof(IPAddressFamily),
194 .sname = "IPAddressFamily",
195};
196LCRYPTO_ALIAS(IPAddressFamily_it);
197
198static const ASN1_TEMPLATE IPAddrBlocks_item_tt = {
199 .flags = ASN1_TFLG_SEQUENCE_OF,
200 .tag = 0,
201 .offset = 0,
202 .field_name = "IPAddrBlocks",
203 .item = &IPAddressFamily_it,
204};
205
206static const ASN1_ITEM IPAddrBlocks_it = {
207 .itype = ASN1_ITYPE_PRIMITIVE,
208 .utype = -1,
209 .templates = &IPAddrBlocks_item_tt,
210 .tcount = 0,
211 .funcs = NULL,
212 .size = 0,
213 .sname = "IPAddrBlocks",
214};
215
216IPAddressRange *
217d2i_IPAddressRange(IPAddressRange **a, const unsigned char **in, long len)
218{
219 return (IPAddressRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
220 &IPAddressRange_it);
221}
222LCRYPTO_ALIAS(d2i_IPAddressRange);
223
224int
225i2d_IPAddressRange(IPAddressRange *a, unsigned char **out)
226{
227 return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressRange_it);
228}
229LCRYPTO_ALIAS(i2d_IPAddressRange);
230
231IPAddressRange *
232IPAddressRange_new(void)
233{
234 return (IPAddressRange *)ASN1_item_new(&IPAddressRange_it);
235}
236LCRYPTO_ALIAS(IPAddressRange_new);
237
238void
239IPAddressRange_free(IPAddressRange *a)
240{
241 ASN1_item_free((ASN1_VALUE *)a, &IPAddressRange_it);
242}
243LCRYPTO_ALIAS(IPAddressRange_free);
244
245IPAddressOrRange *
246d2i_IPAddressOrRange(IPAddressOrRange **a, const unsigned char **in, long len)
247{
248 return (IPAddressOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
249 &IPAddressOrRange_it);
250}
251LCRYPTO_ALIAS(d2i_IPAddressOrRange);
252
253int
254i2d_IPAddressOrRange(IPAddressOrRange *a, unsigned char **out)
255{
256 return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressOrRange_it);
257}
258LCRYPTO_ALIAS(i2d_IPAddressOrRange);
259
260IPAddressOrRange *
261IPAddressOrRange_new(void)
262{
263 return (IPAddressOrRange *)ASN1_item_new(&IPAddressOrRange_it);
264}
265LCRYPTO_ALIAS(IPAddressOrRange_new);
266
267void
268IPAddressOrRange_free(IPAddressOrRange *a)
269{
270 ASN1_item_free((ASN1_VALUE *)a, &IPAddressOrRange_it);
271}
272LCRYPTO_ALIAS(IPAddressOrRange_free);
273
274IPAddressChoice *
275d2i_IPAddressChoice(IPAddressChoice **a, const unsigned char **in, long len)
276{
277 return (IPAddressChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
278 &IPAddressChoice_it);
279}
280LCRYPTO_ALIAS(d2i_IPAddressChoice);
281
282int
283i2d_IPAddressChoice(IPAddressChoice *a, unsigned char **out)
284{
285 return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressChoice_it);
286}
287LCRYPTO_ALIAS(i2d_IPAddressChoice);
288
289IPAddressChoice *
290IPAddressChoice_new(void)
291{
292 return (IPAddressChoice *)ASN1_item_new(&IPAddressChoice_it);
293}
294LCRYPTO_ALIAS(IPAddressChoice_new);
295
296void
297IPAddressChoice_free(IPAddressChoice *a)
298{
299 ASN1_item_free((ASN1_VALUE *)a, &IPAddressChoice_it);
300}
301LCRYPTO_ALIAS(IPAddressChoice_free);
302
303IPAddressFamily *
304d2i_IPAddressFamily(IPAddressFamily **a, const unsigned char **in, long len)
305{
306 return (IPAddressFamily *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
307 &IPAddressFamily_it);
308}
309LCRYPTO_ALIAS(d2i_IPAddressFamily);
310
311int
312i2d_IPAddressFamily(IPAddressFamily *a, unsigned char **out)
313{
314 return ASN1_item_i2d((ASN1_VALUE *)a, out, &IPAddressFamily_it);
315}
316LCRYPTO_ALIAS(i2d_IPAddressFamily);
317
318IPAddressFamily *
319IPAddressFamily_new(void)
320{
321 return (IPAddressFamily *)ASN1_item_new(&IPAddressFamily_it);
322}
323LCRYPTO_ALIAS(IPAddressFamily_new);
324
325void
326IPAddressFamily_free(IPAddressFamily *a)
327{
328 ASN1_item_free((ASN1_VALUE *)a, &IPAddressFamily_it);
329}
330LCRYPTO_ALIAS(IPAddressFamily_free);
331
332/*
333 * Convenience accessors for IPAddressFamily.
334 */
335
336static int
337IPAddressFamily_type(IPAddressFamily *af)
338{
339 /* XXX - can af->ipAddressChoice == NULL actually happen? */
340 if (af == NULL || af->ipAddressChoice == NULL)
341 return -1;
342
343 switch (af->ipAddressChoice->type) {
344 case IPAddressChoice_inherit:
345 case IPAddressChoice_addressesOrRanges:
346 return af->ipAddressChoice->type;
347 default:
348 return -1;
349 }
350}
351
352static IPAddressOrRanges *
353IPAddressFamily_addressesOrRanges(IPAddressFamily *af)
354{
355 if (IPAddressFamily_type(af) == IPAddressChoice_addressesOrRanges)
356 return af->ipAddressChoice->u.addressesOrRanges;
357
358 return NULL;
359}
360
361static ASN1_NULL *
362IPAddressFamily_inheritance(IPAddressFamily *af)
363{
364 if (IPAddressFamily_type(af) == IPAddressChoice_inherit)
365 return af->ipAddressChoice->u.inherit;
366
367 return NULL;
368}
369
370static int
371IPAddressFamily_set_inheritance(IPAddressFamily *af)
372{
373 if (IPAddressFamily_addressesOrRanges(af) != NULL)
374 return 0;
375
376 if (IPAddressFamily_inheritance(af) != NULL)
377 return 1;
378
379 if ((af->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
380 return 0;
381 af->ipAddressChoice->type = IPAddressChoice_inherit;
382
383 return 1;
384}
385
386/*
387 * How much buffer space do we need for a raw address?
388 */
389#define ADDR_RAW_BUF_LEN 16
390
391/*
392 * What's the address length associated with this AFI?
393 */
394static int
395length_from_afi(const unsigned afi, int *length)
396{
397 switch (afi) {
398 case IANA_AFI_IPV4:
399 *length = 4;
400 return 1;
401 case IANA_AFI_IPV6:
402 *length = 16;
403 return 1;
404 default:
405 *length = 0;
406 return 0;
407 }
408}
409
410/*
411 * Get AFI and optional SAFI from an IPAddressFamily. All three out arguments
412 * are optional; if |out_safi| is non-NULL, |safi_is_set| must be non-NULL.
413 */
414static int
415IPAddressFamily_afi_safi(const IPAddressFamily *af, uint16_t *out_afi,
416 uint8_t *out_safi, int *safi_is_set)
417{
418 CBS cbs;
419 uint16_t afi;
420 uint8_t safi = 0;
421 int got_safi = 0;
422
423 if (out_afi != NULL)
424 *out_afi = 0;
425 if (out_safi != NULL) {
426 *out_safi = 0;
427 *safi_is_set = 0;
428 }
429
430 CBS_init(&cbs, af->addressFamily->data, af->addressFamily->length);
431
432 if (!CBS_get_u16(&cbs, &afi))
433 return 0;
434
435 if (afi != IANA_AFI_IPV4 && afi != IANA_AFI_IPV6)
436 return 0;
437
438 /* Fetch the optional SAFI. */
439 if (CBS_len(&cbs) != 0) {
440 if (!CBS_get_u8(&cbs, &safi))
441 return 0;
442 got_safi = 1;
443 }
444
445 /* If there's anything left, it's garbage. */
446 if (CBS_len(&cbs) != 0)
447 return 0;
448
449 /* XXX - error on reserved AFI/SAFI? */
450
451 if (out_afi != NULL)
452 *out_afi = afi;
453
454 if (out_safi != NULL) {
455 *out_safi = safi;
456 *safi_is_set = got_safi;
457 }
458
459 return 1;
460}
461
462static int
463IPAddressFamily_afi(const IPAddressFamily *af, uint16_t *out_afi)
464{
465 return IPAddressFamily_afi_safi(af, out_afi, NULL, NULL);
466}
467
468static int
469IPAddressFamily_afi_is_valid(const IPAddressFamily *af)
470{
471 return IPAddressFamily_afi_safi(af, NULL, NULL, NULL);
472}
473
474static int
475IPAddressFamily_afi_length(const IPAddressFamily *af, int *out_length)
476{
477 uint16_t afi;
478
479 *out_length = 0;
480
481 if (!IPAddressFamily_afi(af, &afi))
482 return 0;
483
484 return length_from_afi(afi, out_length);
485}
486
487#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
488
489/*
490 * Sort comparison function for a sequence of IPAddressFamily.
491 *
492 * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
493 * the ordering: I can read it as meaning that IPv6 without a SAFI
494 * comes before IPv4 with a SAFI, which seems pretty weird. The
495 * examples in appendix B suggest that the author intended the
496 * null-SAFI rule to apply only within a single AFI, which is what I
497 * would have expected and is what the following code implements.
498 */
499static int
500IPAddressFamily_cmp(const IPAddressFamily *const *a_,
501 const IPAddressFamily *const *b_)
502{
503 const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
504 const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
505 int len, cmp;
506
507 len = MINIMUM(a->length, b->length);
508
509 if ((cmp = memcmp(a->data, b->data, len)) != 0)
510 return cmp;
511
512 return a->length - b->length;
513}
514
515static IPAddressFamily *
516IPAddressFamily_find_in_parent(IPAddrBlocks *parent, IPAddressFamily *child_af)
517{
518 int index;
519
520 (void)sk_IPAddressFamily_set_cmp_func(parent, IPAddressFamily_cmp);
521
522 if ((index = sk_IPAddressFamily_find(parent, child_af)) < 0)
523 return NULL;
524
525 return sk_IPAddressFamily_value(parent, index);
526}
527
528/*
529 * Extract the AFI from an IPAddressFamily.
530 *
531 * This is public API. It uses the reserved AFI 0 as an in-band error
532 * while it doesn't care about the reserved AFI 65535...
533 */
534unsigned int
535X509v3_addr_get_afi(const IPAddressFamily *af)
536{
537 uint16_t afi;
538
539 /*
540 * XXX are these NULL checks really sensible? If af is non-NULL, it
541 * should have both addressFamily and ipAddressChoice...
542 */
543 if (af == NULL || af->addressFamily == NULL ||
544 af->addressFamily->data == NULL)
545 return 0;
546
547 if (!IPAddressFamily_afi(af, &afi))
548 return 0;
549
550 return afi;
551}
552LCRYPTO_ALIAS(X509v3_addr_get_afi);
553
554/*
555 * Expand the bitstring form (RFC 3779, section 2.1.2) of an address into
556 * a raw byte array. At the moment this is coded for simplicity, not speed.
557 *
558 * Unused bits in the last octet of |bs| and all bits in subsequent bytes
559 * of |addr| are set to 0 or 1 depending on whether |fill| is 0 or not.
560 */
561static int
562addr_expand(unsigned char *addr, const ASN1_BIT_STRING *bs, const int length,
563 uint8_t fill)
564{
565 if (bs->length < 0 || bs->length > length)
566 return 0;
567
568 if (fill != 0)
569 fill = 0xff;
570
571 if (bs->length > 0) {
572 /* XXX - shouldn't this check ASN1_STRING_FLAG_BITS_LEFT? */
573 uint8_t unused_bits = bs->flags & 7;
574 uint8_t mask = (1 << unused_bits) - 1;
575
576 memcpy(addr, bs->data, bs->length);
577
578 if (fill == 0)
579 addr[bs->length - 1] &= ~mask;
580 else
581 addr[bs->length - 1] |= mask;
582 }
583
584 memset(addr + bs->length, fill, length - bs->length);
585
586 return 1;
587}
588
589/*
590 * Extract the prefix length from a bitstring: 8 * length - unused bits.
591 */
592#define addr_prefix_len(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
593
594/*
595 * i2r handler for one address bitstring.
596 */
597static int
598i2r_address(BIO *out, const unsigned afi, const unsigned char fill,
599 const ASN1_BIT_STRING *bs)
600{
601 unsigned char addr[ADDR_RAW_BUF_LEN];
602 int i, n;
603
604 if (bs->length < 0)
605 return 0;
606 switch (afi) {
607 case IANA_AFI_IPV4:
608 if (!addr_expand(addr, bs, 4, fill))
609 return 0;
610 BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2],
611 addr[3]);
612 break;
613 case IANA_AFI_IPV6:
614 if (!addr_expand(addr, bs, 16, fill))
615 return 0;
616 for (n = 16;
617 n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; n -= 2)
618 continue;
619 for (i = 0; i < n; i += 2)
620 BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1],
621 (i < 14 ? ":" : ""));
622 if (i < 16)
623 BIO_puts(out, ":");
624 if (i == 0)
625 BIO_puts(out, ":");
626 break;
627 default:
628 for (i = 0; i < bs->length; i++)
629 BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""),
630 bs->data[i]);
631 BIO_printf(out, "[%d]", (int)(bs->flags & 7));
632 break;
633 }
634 return 1;
635}
636
637/*
638 * i2r handler for a sequence of addresses and ranges.
639 */
640static int
641i2r_IPAddressOrRanges(BIO *out, const int indent,
642 const IPAddressOrRanges *aors, const unsigned afi)
643{
644 const IPAddressOrRange *aor;
645 const ASN1_BIT_STRING *prefix;
646 const IPAddressRange *range;
647 int i;
648
649 for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
650 aor = sk_IPAddressOrRange_value(aors, i);
651
652 BIO_printf(out, "%*s", indent, "");
653
654 switch (aor->type) {
655 case IPAddressOrRange_addressPrefix:
656 prefix = aor->u.addressPrefix;
657
658 if (!i2r_address(out, afi, 0x00, prefix))
659 return 0;
660 BIO_printf(out, "/%d\n", addr_prefix_len(prefix));
661 continue;
662 case IPAddressOrRange_addressRange:
663 range = aor->u.addressRange;
664
665 if (!i2r_address(out, afi, 0x00, range->min))
666 return 0;
667 BIO_puts(out, "-");
668 if (!i2r_address(out, afi, 0xff, range->max))
669 return 0;
670 BIO_puts(out, "\n");
671 continue;
672 }
673 }
674
675 return 1;
676}
677
678/*
679 * i2r handler for an IPAddrBlocks extension.
680 */
681static int
682i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, void *ext, BIO *out,
683 int indent)
684{
685 const IPAddrBlocks *addr = ext;
686 IPAddressFamily *af;
687 uint16_t afi;
688 uint8_t safi;
689 int i, safi_is_set;
690
691 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
692 af = sk_IPAddressFamily_value(addr, i);
693
694 if (!IPAddressFamily_afi_safi(af, &afi, &safi, &safi_is_set))
695 goto print_addresses;
696
697 switch (afi) {
698 case IANA_AFI_IPV4:
699 BIO_printf(out, "%*sIPv4", indent, "");
700 break;
701 case IANA_AFI_IPV6:
702 BIO_printf(out, "%*sIPv6", indent, "");
703 break;
704 default:
705 BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
706 break;
707 }
708 if (safi_is_set) {
709 switch (safi) {
710 case 1:
711 BIO_puts(out, " (Unicast)");
712 break;
713 case 2:
714 BIO_puts(out, " (Multicast)");
715 break;
716 case 3:
717 BIO_puts(out, " (Unicast/Multicast)");
718 break;
719 case 4:
720 BIO_puts(out, " (MPLS)");
721 break;
722 case 64:
723 BIO_puts(out, " (Tunnel)");
724 break;
725 case 65:
726 BIO_puts(out, " (VPLS)");
727 break;
728 case 66:
729 BIO_puts(out, " (BGP MDT)");
730 break;
731 case 128:
732 BIO_puts(out, " (MPLS-labeled VPN)");
733 break;
734 default:
735 BIO_printf(out, " (Unknown SAFI %u)", safi);
736 break;
737 }
738 }
739
740 print_addresses:
741 switch (IPAddressFamily_type(af)) {
742 case IPAddressChoice_inherit:
743 BIO_puts(out, ": inherit\n");
744 break;
745 case IPAddressChoice_addressesOrRanges:
746 BIO_puts(out, ":\n");
747 if (!i2r_IPAddressOrRanges(out, indent + 2,
748 IPAddressFamily_addressesOrRanges(af), afi))
749 return 0;
750 break;
751 /* XXX - how should we handle -1 here? */
752 }
753 }
754 return 1;
755}
756
757/*
758 * Sort comparison function for a sequence of IPAddressOrRange
759 * elements.
760 *
761 * There's no sane answer we can give if addr_expand() fails, and an
762 * assertion failure on externally supplied data is seriously uncool,
763 * so we just arbitrarily declare that if given invalid inputs this
764 * function returns -1. If this messes up your preferred sort order
765 * for garbage input, tough noogies.
766 */
767static int
768IPAddressOrRange_cmp(const IPAddressOrRange *a, const IPAddressOrRange *b,
769 const int length)
770{
771 unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
772 int prefix_len_a = 0, prefix_len_b = 0;
773 int r;
774
775 switch (a->type) {
776 case IPAddressOrRange_addressPrefix:
777 if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
778 return -1;
779 prefix_len_a = addr_prefix_len(a->u.addressPrefix);
780 break;
781 case IPAddressOrRange_addressRange:
782 if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
783 return -1;
784 prefix_len_a = length * 8;
785 break;
786 }
787
788 switch (b->type) {
789 case IPAddressOrRange_addressPrefix:
790 if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
791 return -1;
792 prefix_len_b = addr_prefix_len(b->u.addressPrefix);
793 break;
794 case IPAddressOrRange_addressRange:
795 if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
796 return -1;
797 prefix_len_b = length * 8;
798 break;
799 }
800
801 if ((r = memcmp(addr_a, addr_b, length)) != 0)
802 return r;
803 else
804 return prefix_len_a - prefix_len_b;
805}
806
807/*
808 * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
809 * comparison routines are only allowed two arguments.
810 */
811static int
812v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
813 const IPAddressOrRange *const *b)
814{
815 return IPAddressOrRange_cmp(*a, *b, 4);
816}
817
818/*
819 * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
820 * comparison routines are only allowed two arguments.
821 */
822static int
823v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
824 const IPAddressOrRange *const *b)
825{
826 return IPAddressOrRange_cmp(*a, *b, 16);
827}
828
829/*
830 * Calculate whether a range collapses to a prefix.
831 * See last paragraph of RFC 3779 2.2.3.7.
832 *
833 * It's the caller's responsibility to ensure that min <= max.
834 */
835static int
836range_should_be_prefix(const unsigned char *min, const unsigned char *max,
837 const int length)
838{
839 unsigned char mask;
840 int i, j;
841
842 for (i = 0; i < length && min[i] == max[i]; i++)
843 continue;
844 for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xff; j--)
845 continue;
846 if (i < j)
847 return -1;
848 if (i > j)
849 return i * 8;
850 mask = min[i] ^ max[i];
851 switch (mask) {
852 case 0x01:
853 j = 7;
854 break;
855 case 0x03:
856 j = 6;
857 break;
858 case 0x07:
859 j = 5;
860 break;
861 case 0x0f:
862 j = 4;
863 break;
864 case 0x1f:
865 j = 3;
866 break;
867 case 0x3f:
868 j = 2;
869 break;
870 case 0x7f:
871 j = 1;
872 break;
873 default:
874 return -1;
875 }
876 if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
877 return -1;
878 else
879 return i * 8 + j;
880}
881
882/*
883 * Fill IPAddressOrRange with bit string encoding of a prefix - RFC 3779, 2.1.1.
884 */
885static int
886make_addressPrefix(IPAddressOrRange **out_aor, uint8_t *addr, uint32_t afi,
887 int prefix_len)
888{
889 IPAddressOrRange *aor = NULL;
890 int afi_len, num_bits, num_octets;
891 uint8_t unused_bits;
892
893 if (prefix_len < 0)
894 goto err;
895
896 if (!length_from_afi(afi, &afi_len))
897 goto err;
898 if (prefix_len > 8 * afi_len)
899 goto err;
900
901 num_octets = (prefix_len + 7) / 8;
902 num_bits = prefix_len % 8;
903
904 unused_bits = 0;
905 if (num_bits > 0)
906 unused_bits = 8 - num_bits;
907
908 if ((aor = IPAddressOrRange_new()) == NULL)
909 goto err;
910
911 aor->type = IPAddressOrRange_addressPrefix;
912
913 if ((aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
914 goto err;
915 if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, num_octets))
916 goto err;
917 if (!asn1_abs_set_unused_bits(aor->u.addressPrefix, unused_bits))
918 goto err;
919
920 *out_aor = aor;
921 return 1;
922
923 err:
924 IPAddressOrRange_free(aor);
925 return 0;
926}
927
928static uint8_t
929count_trailing_zeroes(uint8_t octet)
930{
931 uint8_t count = 0;
932
933 if (octet == 0)
934 return 8;
935
936 while ((octet & (1 << count)) == 0)
937 count++;
938
939 return count;
940}
941
942static int
943trim_end_u8(CBS *cbs, uint8_t trim)
944{
945 uint8_t octet;
946
947 while (CBS_len(cbs) > 0) {
948 if (!CBS_peek_last_u8(cbs, &octet))
949 return 0;
950 if (octet != trim)
951 return 1;
952 if (!CBS_get_last_u8(cbs, &octet))
953 return 0;
954 }
955
956 return 1;
957}
958
959/*
960 * Populate IPAddressOrRange with bit string encoding of a range, see
961 * RFC 3779, 2.1.2.
962 */
963static int
964make_addressRange(IPAddressOrRange **out_aor, uint8_t *min, uint8_t *max,
965 uint32_t afi, int length)
966{
967 IPAddressOrRange *aor = NULL;
968 IPAddressRange *range;
969 int prefix_len;
970 CBS cbs;
971 size_t max_len, min_len;
972 uint8_t unused_bits_min, unused_bits_max;
973 uint8_t octet;
974
975 if (memcmp(min, max, length) > 0)
976 goto err;
977
978 /*
979 * RFC 3779, 2.2.3.6 - a range that can be expressed as a prefix
980 * must be encoded as a prefix.
981 */
982
983 if ((prefix_len = range_should_be_prefix(min, max, length)) >= 0)
984 return make_addressPrefix(out_aor, min, afi, prefix_len);
985
986 /*
987 * The bit string representing min is formed by removing all its
988 * trailing zero bits, so remove all trailing zero octets and count
989 * the trailing zero bits of the last octet.
990 */
991
992 CBS_init(&cbs, min, length);
993
994 if (!trim_end_u8(&cbs, 0x00))
995 goto err;
996
997 unused_bits_min = 0;
998 if ((min_len = CBS_len(&cbs)) > 0) {
999 if (!CBS_peek_last_u8(&cbs, &octet))
1000 goto err;
1001
1002 unused_bits_min = count_trailing_zeroes(octet);
1003 }
1004
1005 /*
1006 * The bit string representing max is formed by removing all its
1007 * trailing one bits, so remove all trailing 0xff octets and count
1008 * the trailing ones of the last octet.
1009 */
1010
1011 CBS_init(&cbs, max, length);
1012
1013 if (!trim_end_u8(&cbs, 0xff))
1014 goto err;
1015
1016 unused_bits_max = 0;
1017 if ((max_len = CBS_len(&cbs)) > 0) {
1018 if (!CBS_peek_last_u8(&cbs, &octet))
1019 goto err;
1020
1021 unused_bits_max = count_trailing_zeroes(octet + 1);
1022 }
1023
1024 /*
1025 * Populate IPAddressOrRange.
1026 */
1027
1028 if ((aor = IPAddressOrRange_new()) == NULL)
1029 goto err;
1030
1031 aor->type = IPAddressOrRange_addressRange;
1032
1033 if ((range = aor->u.addressRange = IPAddressRange_new()) == NULL)
1034 goto err;
1035
1036 if (!ASN1_BIT_STRING_set(range->min, min, min_len))
1037 goto err;
1038 if (!asn1_abs_set_unused_bits(range->min, unused_bits_min))
1039 goto err;
1040
1041 if (!ASN1_BIT_STRING_set(range->max, max, max_len))
1042 goto err;
1043 if (!asn1_abs_set_unused_bits(range->max, unused_bits_max))
1044 goto err;
1045
1046 *out_aor = aor;
1047
1048 return 1;
1049
1050 err:
1051 IPAddressOrRange_free(aor);
1052 return 0;
1053}
1054
1055/*
1056 * Construct a new address family or find an existing one.
1057 */
1058static IPAddressFamily *
1059make_IPAddressFamily(IPAddrBlocks *addr, const unsigned afi,
1060 const unsigned *safi)
1061{
1062 IPAddressFamily *af = NULL;
1063 CBB cbb;
1064 CBS cbs;
1065 uint8_t *key = NULL;
1066 size_t keylen;
1067 int i;
1068
1069 if (!CBB_init(&cbb, 0))
1070 goto err;
1071
1072 if (afi != IANA_AFI_IPV4 && afi != IANA_AFI_IPV6)
1073 goto err;
1074 if (!CBB_add_u16(&cbb, afi))
1075 goto err;
1076
1077 if (safi != NULL) {
1078 if (*safi > 255)
1079 goto err;
1080 if (!CBB_add_u8(&cbb, *safi))
1081 goto err;
1082 }
1083
1084 if (!CBB_finish(&cbb, &key, &keylen))
1085 goto err;
1086
1087 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
1088 af = sk_IPAddressFamily_value(addr, i);
1089
1090 CBS_init(&cbs, af->addressFamily->data,
1091 af->addressFamily->length);
1092 if (CBS_mem_equal(&cbs, key, keylen))
1093 goto done;
1094 }
1095
1096 if ((af = IPAddressFamily_new()) == NULL)
1097 goto err;
1098 if (!ASN1_OCTET_STRING_set(af->addressFamily, key, keylen))
1099 goto err;
1100 if (!sk_IPAddressFamily_push(addr, af))
1101 goto err;
1102
1103 done:
1104 free(key);
1105
1106 return af;
1107
1108 err:
1109 CBB_cleanup(&cbb);
1110 free(key);
1111 IPAddressFamily_free(af);
1112
1113 return NULL;
1114}
1115
1116/*
1117 * Add an inheritance element.
1118 */
1119int
1120X509v3_addr_add_inherit(IPAddrBlocks *addr, const unsigned afi,
1121 const unsigned *safi)
1122{
1123 IPAddressFamily *af;
1124
1125 if ((af = make_IPAddressFamily(addr, afi, safi)) == NULL)
1126 return 0;
1127
1128 return IPAddressFamily_set_inheritance(af);
1129}
1130LCRYPTO_ALIAS(X509v3_addr_add_inherit);
1131
1132/*
1133 * Construct an IPAddressOrRange sequence, or return an existing one.
1134 */
1135static IPAddressOrRanges *
1136make_prefix_or_range(IPAddrBlocks *addr, const unsigned afi,
1137 const unsigned *safi)
1138{
1139 IPAddressFamily *af;
1140 IPAddressOrRanges *aors = NULL;
1141
1142 if ((af = make_IPAddressFamily(addr, afi, safi)) == NULL)
1143 return NULL;
1144
1145 if (IPAddressFamily_inheritance(af) != NULL)
1146 return NULL;
1147
1148 if ((aors = IPAddressFamily_addressesOrRanges(af)) != NULL)
1149 return aors;
1150
1151 if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
1152 return NULL;
1153
1154 switch (afi) {
1155 case IANA_AFI_IPV4:
1156 (void)sk_IPAddressOrRange_set_cmp_func(aors,
1157 v4IPAddressOrRange_cmp);
1158 break;
1159 case IANA_AFI_IPV6:
1160 (void)sk_IPAddressOrRange_set_cmp_func(aors,
1161 v6IPAddressOrRange_cmp);
1162 break;
1163 }
1164
1165 af->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
1166 af->ipAddressChoice->u.addressesOrRanges = aors;
1167
1168 return aors;
1169}
1170
1171/*
1172 * Add a prefix.
1173 */
1174int
1175X509v3_addr_add_prefix(IPAddrBlocks *addr, const unsigned afi,
1176 const unsigned *safi, unsigned char *a, const int prefix_len)
1177{
1178 IPAddressOrRanges *aors;
1179 IPAddressOrRange *aor;
1180
1181 if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL)
1182 return 0;
1183
1184 if (!make_addressPrefix(&aor, a, afi, prefix_len))
1185 return 0;
1186
1187 if (sk_IPAddressOrRange_push(aors, aor) <= 0) {
1188 IPAddressOrRange_free(aor);
1189 return 0;
1190 }
1191
1192 return 1;
1193}
1194LCRYPTO_ALIAS(X509v3_addr_add_prefix);
1195
1196/*
1197 * Add a range.
1198 */
1199int
1200X509v3_addr_add_range(IPAddrBlocks *addr, const unsigned afi,
1201 const unsigned *safi, unsigned char *min, unsigned char *max)
1202{
1203 IPAddressOrRanges *aors;
1204 IPAddressOrRange *aor;
1205 int length;
1206
1207 if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL)
1208 return 0;
1209
1210 if (!length_from_afi(afi, &length))
1211 return 0;
1212
1213 if (!make_addressRange(&aor, min, max, afi, length))
1214 return 0;
1215
1216 if (sk_IPAddressOrRange_push(aors, aor) <= 0) {
1217 IPAddressOrRange_free(aor);
1218 return 0;
1219 }
1220
1221 return 1;
1222}
1223LCRYPTO_ALIAS(X509v3_addr_add_range);
1224
1225static int
1226extract_min_max_bitstr(IPAddressOrRange *aor, ASN1_BIT_STRING **out_min,
1227 ASN1_BIT_STRING **out_max)
1228{
1229 switch (aor->type) {
1230 case IPAddressOrRange_addressPrefix:
1231 *out_min = *out_max = aor->u.addressPrefix;
1232 return 1;
1233 case IPAddressOrRange_addressRange:
1234 *out_min = aor->u.addressRange->min;
1235 *out_max = aor->u.addressRange->max;
1236 return 1;
1237 default:
1238 return 0;
1239 }
1240}
1241
1242/*
1243 * Extract min and max values from an IPAddressOrRange.
1244 */
1245static int
1246extract_min_max(IPAddressOrRange *aor, unsigned char *min, unsigned char *max,
1247 int length)
1248{
1249 ASN1_BIT_STRING *min_bitstr, *max_bitstr;
1250
1251 if (aor == NULL || min == NULL || max == NULL)
1252 return 0;
1253
1254 if (!extract_min_max_bitstr(aor, &min_bitstr, &max_bitstr))
1255 return 0;
1256
1257 if (!addr_expand(min, min_bitstr, length, 0))
1258 return 0;
1259
1260 return addr_expand(max, max_bitstr, length, 1);
1261}
1262
1263/*
1264 * Public wrapper for extract_min_max().
1265 */
1266int
1267X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
1268 unsigned char *min, unsigned char *max, const int length)
1269{
1270 int afi_len;
1271
1272 if (!length_from_afi(afi, &afi_len))
1273 return 0;
1274
1275 if (length < afi_len)
1276 return 0;
1277
1278 if (!extract_min_max(aor, min, max, afi_len))
1279 return 0;
1280
1281 return afi_len;
1282}
1283LCRYPTO_ALIAS(X509v3_addr_get_range);
1284
1285/*
1286 * Check whether an IPAddrBLocks is in canonical form.
1287 */
1288int
1289X509v3_addr_is_canonical(IPAddrBlocks *addr)
1290{
1291 unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
1292 unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
1293 IPAddressFamily *af;
1294 IPAddressOrRanges *aors;
1295 IPAddressOrRange *aor, *aor_a, *aor_b;
1296 int i, j, k, length;
1297
1298 /*
1299 * Empty extension is canonical.
1300 */
1301 if (addr == NULL)
1302 return 1;
1303
1304 /*
1305 * Check whether the top-level list is in order.
1306 */
1307 for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
1308 const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
1309 const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
1310
1311 /* Check that both have valid AFIs before comparing them. */
1312 if (!IPAddressFamily_afi_is_valid(a))
1313 return 0;
1314 if (!IPAddressFamily_afi_is_valid(b))
1315 return 0;
1316
1317 if (IPAddressFamily_cmp(&a, &b) >= 0)
1318 return 0;
1319 }
1320
1321 /*
1322 * Top level's ok, now check each address family.
1323 */
1324 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
1325 af = sk_IPAddressFamily_value(addr, i);
1326
1327 if (!IPAddressFamily_afi_length(af, &length))
1328 return 0;
1329
1330 /*
1331 * If this family has an inheritance element, it is canonical.
1332 */
1333 if (IPAddressFamily_inheritance(af) != NULL)
1334 continue;
1335
1336 /*
1337 * If this family has neither an inheritance element nor an
1338 * addressesOrRanges, we don't know what this is.
1339 */
1340 if ((aors = IPAddressFamily_addressesOrRanges(af)) == NULL)
1341 return 0;
1342
1343 if (sk_IPAddressOrRange_num(aors) == 0)
1344 return 0;
1345
1346 for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
1347 aor_a = sk_IPAddressOrRange_value(aors, j);
1348 aor_b = sk_IPAddressOrRange_value(aors, j + 1);
1349
1350 if (!extract_min_max(aor_a, a_min, a_max, length) ||
1351 !extract_min_max(aor_b, b_min, b_max, length))
1352 return 0;
1353
1354 /*
1355 * Punt misordered list, overlapping start, or inverted
1356 * range.
1357 */
1358 if (memcmp(a_min, b_min, length) >= 0 ||
1359 memcmp(a_min, a_max, length) > 0 ||
1360 memcmp(b_min, b_max, length) > 0)
1361 return 0;
1362
1363 /*
1364 * Punt if adjacent or overlapping. Check for adjacency
1365 * by subtracting one from b_min first.
1366 */
1367 for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--)
1368 continue;
1369 if (memcmp(a_max, b_min, length) >= 0)
1370 return 0;
1371
1372 /*
1373 * Check for range that should be expressed as a prefix.
1374 */
1375 if (aor_a->type == IPAddressOrRange_addressPrefix)
1376 continue;
1377
1378 if (range_should_be_prefix(a_min, a_max, length) >= 0)
1379 return 0;
1380 }
1381
1382 /*
1383 * Check final range to see if it's inverted or should be a
1384 * prefix.
1385 */
1386 aor = sk_IPAddressOrRange_value(aors, j);
1387 if (aor->type == IPAddressOrRange_addressRange) {
1388 if (!extract_min_max(aor, a_min, a_max, length))
1389 return 0;
1390 if (memcmp(a_min, a_max, length) > 0)
1391 return 0;
1392 if (range_should_be_prefix(a_min, a_max, length) >= 0)
1393 return 0;
1394 }
1395 }
1396
1397 /*
1398 * If we made it through all that, we're happy.
1399 */
1400 return 1;
1401}
1402LCRYPTO_ALIAS(X509v3_addr_is_canonical);
1403
1404/*
1405 * Whack an IPAddressOrRanges into canonical form.
1406 */
1407static int
1408IPAddressOrRanges_canonize(IPAddressOrRanges *aors, const unsigned afi)
1409{
1410 IPAddressOrRange *a, *b, *merged;
1411 unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
1412 unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
1413 int i, j, length;
1414
1415 if (!length_from_afi(afi, &length))
1416 return 0;
1417
1418 /*
1419 * Sort the IPAddressOrRanges sequence.
1420 */
1421 sk_IPAddressOrRange_sort(aors);
1422
1423 /*
1424 * Clean up representation issues, punt on duplicates or overlaps.
1425 */
1426 for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
1427 a = sk_IPAddressOrRange_value(aors, i);
1428 b = sk_IPAddressOrRange_value(aors, i + 1);
1429
1430 if (!extract_min_max(a, a_min, a_max, length) ||
1431 !extract_min_max(b, b_min, b_max, length))
1432 return 0;
1433
1434 /*
1435 * Punt inverted ranges.
1436 */
1437 if (memcmp(a_min, a_max, length) > 0 ||
1438 memcmp(b_min, b_max, length) > 0)
1439 return 0;
1440
1441 /*
1442 * Punt overlaps.
1443 */
1444 if (memcmp(a_max, b_min, length) >= 0)
1445 return 0;
1446
1447 /*
1448 * Merge if a and b are adjacent. We check for
1449 * adjacency by subtracting one from b_min first.
1450 */
1451 for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--)
1452 continue;
1453
1454 if (memcmp(a_max, b_min, length) != 0)
1455 continue;
1456
1457 if (!make_addressRange(&merged, a_min, b_max, afi, length))
1458 return 0;
1459 sk_IPAddressOrRange_set(aors, i, merged);
1460 (void)sk_IPAddressOrRange_delete(aors, i + 1);
1461 IPAddressOrRange_free(a);
1462 IPAddressOrRange_free(b);
1463 i--;
1464 }
1465
1466 /*
1467 * Check for inverted final range.
1468 */
1469 a = sk_IPAddressOrRange_value(aors, i);
1470 if (a != NULL && a->type == IPAddressOrRange_addressRange) {
1471 if (!extract_min_max(a, a_min, a_max, length))
1472 return 0;
1473 if (memcmp(a_min, a_max, length) > 0)
1474 return 0;
1475 }
1476
1477 return 1;
1478}
1479
1480/*
1481 * Whack an IPAddrBlocks extension into canonical form.
1482 */
1483int
1484X509v3_addr_canonize(IPAddrBlocks *addr)
1485{
1486 IPAddressFamily *af;
1487 IPAddressOrRanges *aors;
1488 uint16_t afi;
1489 int i;
1490
1491 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
1492 af = sk_IPAddressFamily_value(addr, i);
1493
1494 /* Check AFI/SAFI here - IPAddressFamily_cmp() can't error. */
1495 if (!IPAddressFamily_afi(af, &afi))
1496 return 0;
1497
1498 if ((aors = IPAddressFamily_addressesOrRanges(af)) == NULL)
1499 continue;
1500
1501 if (!IPAddressOrRanges_canonize(aors, afi))
1502 return 0;
1503 }
1504
1505 (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
1506 sk_IPAddressFamily_sort(addr);
1507
1508 return X509v3_addr_is_canonical(addr);
1509}
1510LCRYPTO_ALIAS(X509v3_addr_canonize);
1511
1512/*
1513 * v2i handler for the IPAddrBlocks extension.
1514 */
1515static void *
1516v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx,
1517 STACK_OF(CONF_VALUE)*values)
1518{
1519 static const char v4addr_chars[] = "0123456789.";
1520 static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
1521 IPAddrBlocks *addr = NULL;
1522 char *s = NULL, *t;
1523 int i;
1524
1525 if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
1526 X509V3error(ERR_R_MALLOC_FAILURE);
1527 return NULL;
1528 }
1529
1530 for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
1531 CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
1532 unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
1533 unsigned afi, *safi = NULL, safi_;
1534 const char *addr_chars = NULL;
1535 const char *errstr;
1536 int prefix_len, i1, i2, delim, length;
1537
1538 if (!name_cmp(val->name, "IPv4")) {
1539 afi = IANA_AFI_IPV4;
1540 } else if (!name_cmp(val->name, "IPv6")) {
1541 afi = IANA_AFI_IPV6;
1542 } else if (!name_cmp(val->name, "IPv4-SAFI")) {
1543 afi = IANA_AFI_IPV4;
1544 safi = &safi_;
1545 } else if (!name_cmp(val->name, "IPv6-SAFI")) {
1546 afi = IANA_AFI_IPV6;
1547 safi = &safi_;
1548 } else {
1549 X509V3error(X509V3_R_EXTENSION_NAME_ERROR);
1550 X509V3_conf_err(val);
1551 goto err;
1552 }
1553
1554 switch (afi) {
1555 case IANA_AFI_IPV4:
1556 addr_chars = v4addr_chars;
1557 break;
1558 case IANA_AFI_IPV6:
1559 addr_chars = v6addr_chars;
1560 break;
1561 }
1562
1563 if (!length_from_afi(afi, &length))
1564 goto err;
1565
1566 /*
1567 * Handle SAFI, if any, and strdup() so we can null-terminate
1568 * the other input values.
1569 */
1570 if (safi != NULL) {
1571 unsigned long parsed_safi;
1572 int saved_errno = errno;
1573
1574 errno = 0;
1575 parsed_safi = strtoul(val->value, &t, 0);
1576
1577 /* Value must be present, then a tab, space or colon. */
1578 if (val->value[0] == '\0' ||
1579 (*t != '\t' && *t != ' ' && *t != ':')) {
1580 X509V3error(X509V3_R_INVALID_SAFI);
1581 X509V3_conf_err(val);
1582 goto err;
1583 }
1584 /* Range and overflow check. */
1585 if ((errno == ERANGE && parsed_safi == ULONG_MAX) ||
1586 parsed_safi > 0xff) {
1587 X509V3error(X509V3_R_INVALID_SAFI);
1588 X509V3_conf_err(val);
1589 goto err;
1590 }
1591 errno = saved_errno;
1592
1593 *safi = parsed_safi;
1594
1595 /* Check possible whitespace is followed by a colon. */
1596 t += strspn(t, " \t");
1597 if (*t != ':') {
1598 X509V3error(X509V3_R_INVALID_SAFI);
1599 X509V3_conf_err(val);
1600 goto err;
1601 }
1602
1603 /* Skip over colon. */
1604 t++;
1605
1606 /* Then over any trailing whitespace. */
1607 t += strspn(t, " \t");
1608
1609 s = strdup(t);
1610 } else {
1611 s = strdup(val->value);
1612 }
1613 if (s == NULL) {
1614 X509V3error(ERR_R_MALLOC_FAILURE);
1615 goto err;
1616 }
1617
1618 /*
1619 * Check for inheritance. Not worth additional complexity to
1620 * optimize this (seldom-used) case.
1621 */
1622 if (strcmp(s, "inherit") == 0) {
1623 if (!X509v3_addr_add_inherit(addr, afi, safi)) {
1624 X509V3error(X509V3_R_INVALID_INHERITANCE);
1625 X509V3_conf_err(val);
1626 goto err;
1627 }
1628 free(s);
1629 s = NULL;
1630 continue;
1631 }
1632
1633 i1 = strspn(s, addr_chars);
1634 i2 = i1 + strspn(s + i1, " \t");
1635 delim = s[i2++];
1636 s[i1] = '\0';
1637
1638 if (a2i_ipadd(min, s) != length) {
1639 X509V3error(X509V3_R_INVALID_IPADDRESS);
1640 X509V3_conf_err(val);
1641 goto err;
1642 }
1643
1644 switch (delim) {
1645 case '/':
1646 /* length contains the size of the address in bytes. */
1647 if (length != 4 && length != 16)
1648 goto err;
1649 prefix_len = strtonum(s + i2, 0, 8 * length, &errstr);
1650 if (errstr != NULL) {
1651 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
1652 X509V3_conf_err(val);
1653 goto err;
1654 }
1655 if (!X509v3_addr_add_prefix(addr, afi, safi, min,
1656 prefix_len)) {
1657 X509V3error(ERR_R_MALLOC_FAILURE);
1658 goto err;
1659 }
1660 break;
1661 case '-':
1662 i1 = i2 + strspn(s + i2, " \t");
1663 i2 = i1 + strspn(s + i1, addr_chars);
1664 if (i1 == i2 || s[i2] != '\0') {
1665 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
1666 X509V3_conf_err(val);
1667 goto err;
1668 }
1669 if (a2i_ipadd(max, s + i1) != length) {
1670 X509V3error(X509V3_R_INVALID_IPADDRESS);
1671 X509V3_conf_err(val);
1672 goto err;
1673 }
1674 if (memcmp(min, max, length) > 0) {
1675 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
1676 X509V3_conf_err(val);
1677 goto err;
1678 }
1679 if (!X509v3_addr_add_range(addr, afi, safi, min, max)) {
1680 X509V3error(ERR_R_MALLOC_FAILURE);
1681 goto err;
1682 }
1683 break;
1684 case '\0':
1685 if (!X509v3_addr_add_prefix(addr, afi, safi, min,
1686 length * 8)) {
1687 X509V3error(ERR_R_MALLOC_FAILURE);
1688 goto err;
1689 }
1690 break;
1691 default:
1692 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
1693 X509V3_conf_err(val);
1694 goto err;
1695 }
1696
1697 free(s);
1698 s = NULL;
1699 }
1700
1701 /*
1702 * Canonize the result, then we're done.
1703 */
1704 if (!X509v3_addr_canonize(addr))
1705 goto err;
1706 return addr;
1707
1708 err:
1709 free(s);
1710 sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
1711 return NULL;
1712}
1713
1714/*
1715 * OpenSSL dispatch
1716 */
1717static const X509V3_EXT_METHOD x509v3_ext_sbgp_ipAddrBlock = {
1718 .ext_nid = NID_sbgp_ipAddrBlock,
1719 .ext_flags = 0,
1720 .it = &IPAddrBlocks_it,
1721 .ext_new = NULL,
1722 .ext_free = NULL,
1723 .d2i = NULL,
1724 .i2d = NULL,
1725 .i2s = NULL,
1726 .s2i = NULL,
1727 .i2v = NULL,
1728 .v2i = v2i_IPAddrBlocks,
1729 .i2r = i2r_IPAddrBlocks,
1730 .r2i = NULL,
1731 .usr_data = NULL,
1732};
1733
1734const X509V3_EXT_METHOD *
1735x509v3_ext_method_sbgp_ipAddrBlock(void)
1736{
1737 return &x509v3_ext_sbgp_ipAddrBlock;
1738}
1739
1740/*
1741 * Figure out whether extension uses inheritance.
1742 */
1743int
1744X509v3_addr_inherits(IPAddrBlocks *addr)
1745{
1746 IPAddressFamily *af;
1747 int i;
1748
1749 if (addr == NULL)
1750 return 0;
1751
1752 for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
1753 af = sk_IPAddressFamily_value(addr, i);
1754
1755 if (IPAddressFamily_inheritance(af) != NULL)
1756 return 1;
1757 }
1758
1759 return 0;
1760}
1761LCRYPTO_ALIAS(X509v3_addr_inherits);
1762
1763/*
1764 * Figure out whether parent contains child.
1765 *
1766 * This only works correctly if both parent and child are in canonical form.
1767 */
1768static int
1769addr_contains(IPAddressOrRanges *parent, IPAddressOrRanges *child, int length)
1770{
1771 IPAddressOrRange *child_aor, *parent_aor;
1772 uint8_t parent_min[ADDR_RAW_BUF_LEN], parent_max[ADDR_RAW_BUF_LEN];
1773 uint8_t child_min[ADDR_RAW_BUF_LEN], child_max[ADDR_RAW_BUF_LEN];
1774 int p, c;
1775
1776 if (child == NULL || parent == child)
1777 return 1;
1778 if (parent == NULL)
1779 return 0;
1780
1781 p = 0;
1782 for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
1783 child_aor = sk_IPAddressOrRange_value(child, c);
1784
1785 if (!extract_min_max(child_aor, child_min, child_max, length))
1786 return 0;
1787
1788 for (;; p++) {
1789 if (p >= sk_IPAddressOrRange_num(parent))
1790 return 0;
1791
1792 parent_aor = sk_IPAddressOrRange_value(parent, p);
1793
1794 if (!extract_min_max(parent_aor, parent_min, parent_max,
1795 length))
1796 return 0;
1797
1798 if (memcmp(parent_max, child_max, length) < 0)
1799 continue;
1800 if (memcmp(parent_min, child_min, length) > 0)
1801 return 0;
1802 break;
1803 }
1804 }
1805
1806 return 1;
1807}
1808
1809/*
1810 * Test whether |child| is a subset of |parent|.
1811 */
1812int
1813X509v3_addr_subset(IPAddrBlocks *child, IPAddrBlocks *parent)
1814{
1815 IPAddressFamily *child_af, *parent_af;
1816 IPAddressOrRanges *child_aor, *parent_aor;
1817 int i, length;
1818
1819 if (child == NULL || child == parent)
1820 return 1;
1821 if (parent == NULL)
1822 return 0;
1823
1824 if (X509v3_addr_inherits(child) || X509v3_addr_inherits(parent))
1825 return 0;
1826
1827 for (i = 0; i < sk_IPAddressFamily_num(child); i++) {
1828 child_af = sk_IPAddressFamily_value(child, i);
1829
1830 parent_af = IPAddressFamily_find_in_parent(parent, child_af);
1831 if (parent_af == NULL)
1832 return 0;
1833
1834 if (!IPAddressFamily_afi_length(parent_af, &length))
1835 return 0;
1836
1837 child_aor = IPAddressFamily_addressesOrRanges(child_af);
1838 parent_aor = IPAddressFamily_addressesOrRanges(parent_af);
1839
1840 if (!addr_contains(parent_aor, child_aor, length))
1841 return 0;
1842 }
1843 return 1;
1844}
1845LCRYPTO_ALIAS(X509v3_addr_subset);
1846
1847static int
1848verify_error(X509_STORE_CTX *ctx, X509 *cert, int error, int depth)
1849{
1850 if (ctx == NULL)
1851 return 0;
1852
1853 ctx->current_cert = cert;
1854 ctx->error = error;
1855 ctx->error_depth = depth;
1856
1857 return ctx->verify_cb(0, ctx);
1858}
1859
1860/*
1861 * Core code for RFC 3779 2.3 path validation.
1862 *
1863 * Returns 1 for success, 0 on error.
1864 *
1865 * When returning 0, ctx->error MUST be set to an appropriate value other than
1866 * X509_V_OK.
1867 */
1868static int
1869addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain,
1870 IPAddrBlocks *ext)
1871{
1872 IPAddrBlocks *child = NULL, *parent = NULL;
1873 IPAddressFamily *child_af, *parent_af;
1874 IPAddressOrRanges *child_aor, *parent_aor;
1875 X509 *cert = NULL;
1876 int depth = -1;
1877 int i;
1878 unsigned int length;
1879 int ret = 1;
1880
1881 /* We need a non-empty chain to test against. */
1882 if (sk_X509_num(chain) <= 0)
1883 goto err;
1884 /* We need either a store ctx or an extension to work with. */
1885 if (ctx == NULL && ext == NULL)
1886 goto err;
1887 /* If there is a store ctx, it needs a verify_cb. */
1888 if (ctx != NULL && ctx->verify_cb == NULL)
1889 goto err;
1890
1891 /*
1892 * Figure out where to start. If we don't have an extension to check,
1893 * (either extracted from the leaf or passed by the caller), we're done.
1894 * Otherwise, check canonical form and set up for walking up the chain.
1895 */
1896 if (ext == NULL) {
1897 depth = 0;
1898 cert = sk_X509_value(chain, depth);
1899 if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) {
1900 if ((ret = verify_error(ctx, cert,
1901 X509_V_ERR_INVALID_EXTENSION, depth)) == 0)
1902 goto done;
1903 }
1904 if ((ext = cert->rfc3779_addr) == NULL)
1905 goto done;
1906 } else if (!X509v3_addr_is_canonical(ext)) {
1907 if ((ret = verify_error(ctx, cert,
1908 X509_V_ERR_INVALID_EXTENSION, depth)) == 0)
1909 goto done;
1910 }
1911
1912 (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
1913 if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
1914 X509V3error(ERR_R_MALLOC_FAILURE);
1915 if (ctx != NULL)
1916 ctx->error = X509_V_ERR_OUT_OF_MEM;
1917 ret = 0;
1918 goto done;
1919 }
1920
1921 /*
1922 * Now walk up the chain. No cert may list resources that its parent
1923 * doesn't list.
1924 */
1925 for (depth++; depth < sk_X509_num(chain); depth++) {
1926 cert = sk_X509_value(chain, depth);
1927
1928 if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) {
1929 if ((ret = verify_error(ctx, cert,
1930 X509_V_ERR_INVALID_EXTENSION, depth)) == 0)
1931 goto done;
1932 }
1933
1934 if ((parent = cert->rfc3779_addr) == NULL) {
1935 for (i = 0; i < sk_IPAddressFamily_num(child); i++) {
1936 child_af = sk_IPAddressFamily_value(child, i);
1937
1938 if (IPAddressFamily_inheritance(child_af) !=
1939 NULL)
1940 continue;
1941
1942 if ((ret = verify_error(ctx, cert,
1943 X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0)
1944 goto done;
1945 break;
1946 }
1947 continue;
1948 }
1949
1950 /*
1951 * Check that the child's resources are covered by the parent.
1952 * Each covered resource is replaced with the parent's resource
1953 * covering it, so the next iteration will check that the
1954 * parent's resources are covered by the grandparent.
1955 */
1956 for (i = 0; i < sk_IPAddressFamily_num(child); i++) {
1957 child_af = sk_IPAddressFamily_value(child, i);
1958
1959 if ((parent_af = IPAddressFamily_find_in_parent(parent,
1960 child_af)) == NULL) {
1961 /*
1962 * If we have no match in the parent and the
1963 * child inherits, that's fine.
1964 */
1965 if (IPAddressFamily_inheritance(child_af) !=
1966 NULL)
1967 continue;
1968
1969 /* Otherwise the child isn't covered. */
1970 if ((ret = verify_error(ctx, cert,
1971 X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0)
1972 goto done;
1973 break;
1974 }
1975
1976 /* Parent inherits, nothing to do. */
1977 if (IPAddressFamily_inheritance(parent_af) != NULL)
1978 continue;
1979
1980 /* Child inherits. Use parent's address family. */
1981 if (IPAddressFamily_inheritance(child_af) != NULL) {
1982 sk_IPAddressFamily_set(child, i, parent_af);
1983 continue;
1984 }
1985
1986 child_aor = IPAddressFamily_addressesOrRanges(child_af);
1987 parent_aor =
1988 IPAddressFamily_addressesOrRanges(parent_af);
1989
1990 /*
1991 * Child and parent are canonical and neither inherits.
1992 * If either addressesOrRanges is NULL, something's
1993 * very wrong.
1994 */
1995 if (child_aor == NULL || parent_aor == NULL)
1996 goto err;
1997
1998 if (!IPAddressFamily_afi_length(child_af, &length))
1999 goto err;
2000
2001 /* Now check containment and replace or error. */
2002 if (addr_contains(parent_aor, child_aor, length)) {
2003 sk_IPAddressFamily_set(child, i, parent_af);
2004 continue;
2005 }
2006
2007 if ((ret = verify_error(ctx, cert,
2008 X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0)
2009 goto done;
2010 }
2011 }
2012
2013 /*
2014 * Trust anchor can't inherit.
2015 */
2016 if ((parent = cert->rfc3779_addr) != NULL) {
2017 for (i = 0; i < sk_IPAddressFamily_num(parent); i++) {
2018 parent_af = sk_IPAddressFamily_value(parent, i);
2019
2020 if (IPAddressFamily_inheritance(parent_af) == NULL)
2021 continue;
2022
2023 if ((ret = verify_error(ctx, cert,
2024 X509_V_ERR_UNNESTED_RESOURCE, depth)) == 0)
2025 goto done;
2026 }
2027 }
2028
2029 done:
2030 sk_IPAddressFamily_free(child);
2031 return ret;
2032
2033 err:
2034 sk_IPAddressFamily_free(child);
2035
2036 if (ctx != NULL)
2037 ctx->error = X509_V_ERR_UNSPECIFIED;
2038
2039 return 0;
2040}
2041
2042/*
2043 * RFC 3779 2.3 path validation -- called from X509_verify_cert().
2044 */
2045int
2046X509v3_addr_validate_path(X509_STORE_CTX *ctx)
2047{
2048 if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) {
2049 ctx->error = X509_V_ERR_UNSPECIFIED;
2050 return 0;
2051 }
2052 return addr_validate_path_internal(ctx, ctx->chain, NULL);
2053}
2054LCRYPTO_ALIAS(X509v3_addr_validate_path);
2055
2056/*
2057 * RFC 3779 2.3 path validation of an extension.
2058 * Test whether chain covers extension.
2059 */
2060int
2061X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, IPAddrBlocks *ext,
2062 int allow_inheritance)
2063{
2064 if (ext == NULL)
2065 return 1;
2066 if (sk_X509_num(chain) <= 0)
2067 return 0;
2068 if (!allow_inheritance && X509v3_addr_inherits(ext))
2069 return 0;
2070 return addr_validate_path_internal(NULL, chain, ext);
2071}
2072LCRYPTO_ALIAS(X509v3_addr_validate_resource_set);
2073
2074#endif /* OPENSSL_NO_RFC3779 */
diff --git a/src/lib/libcrypto/x509/x509_akey.c b/src/lib/libcrypto/x509/x509_akey.c
deleted file mode 100644
index 926508c4cd..0000000000
--- a/src/lib/libcrypto/x509/x509_akey.c
+++ /dev/null
@@ -1,245 +0,0 @@
1/* $OpenBSD: x509_akey.c,v 1.3 2024/08/31 10:03:03 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
64#include <openssl/conf.h>
65#include <openssl/err.h>
66#include <openssl/x509v3.h>
67
68#include "x509_local.h"
69
70static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
71 AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist);
72static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
73 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
74
75static const X509V3_EXT_METHOD x509v3_ext_authority_key_identifier = {
76 .ext_nid = NID_authority_key_identifier,
77 .ext_flags = X509V3_EXT_MULTILINE,
78 .it = &AUTHORITY_KEYID_it,
79 .ext_new = NULL,
80 .ext_free = NULL,
81 .d2i = NULL,
82 .i2d = NULL,
83 .i2s = NULL,
84 .s2i = NULL,
85 .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_KEYID,
86 .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
87 .i2r = NULL,
88 .r2i = NULL,
89 .usr_data = NULL,
90};
91
92const X509V3_EXT_METHOD *
93x509v3_ext_method_authority_key_identifier(void)
94{
95 return &x509v3_ext_authority_key_identifier;
96}
97
98static STACK_OF(CONF_VALUE) *
99i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, AUTHORITY_KEYID *akeyid,
100 STACK_OF(CONF_VALUE) *extlist)
101{
102 STACK_OF(CONF_VALUE) *free_extlist = NULL;
103 char *tmpstr = NULL;
104
105 if (extlist == NULL) {
106 if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
107 return NULL;
108 }
109
110 if (akeyid->keyid != NULL) {
111 if ((tmpstr = hex_to_string(akeyid->keyid->data,
112 akeyid->keyid->length)) == NULL)
113 goto err;
114 if (!X509V3_add_value("keyid", tmpstr, &extlist))
115 goto err;
116 free(tmpstr);
117 tmpstr = NULL;
118 }
119
120 if (akeyid->issuer != NULL) {
121 if ((extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer,
122 extlist)) == NULL)
123 goto err;
124 }
125
126 if (akeyid->serial != NULL) {
127 if ((tmpstr = hex_to_string(akeyid->serial->data,
128 akeyid->serial->length)) == NULL)
129 goto err;
130 if (!X509V3_add_value("serial", tmpstr, &extlist))
131 goto err;
132 free(tmpstr);
133 tmpstr = NULL;
134 }
135
136 if (sk_CONF_VALUE_num(extlist) <= 0)
137 goto err;
138
139 return extlist;
140
141 err:
142 free(tmpstr);
143 sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
144
145 return NULL;
146}
147
148/*
149 * Currently two options:
150 * keyid: use the issuers subject keyid, the value 'always' means its is
151 * an error if the issuer certificate doesn't have a key id.
152 * issuer: use the issuers cert issuer and serial number. The default is
153 * to only use this if keyid is not present. With the option 'always'
154 * this is always included.
155 */
156static AUTHORITY_KEYID *
157v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
158 STACK_OF(CONF_VALUE) *values)
159{
160 char keyid = 0, issuer = 0;
161 int i;
162 CONF_VALUE *cnf;
163 ASN1_OCTET_STRING *ikeyid = NULL;
164 X509_NAME *isname = NULL;
165 STACK_OF(GENERAL_NAME) *gens = NULL;
166 GENERAL_NAME *gen = NULL;
167 ASN1_INTEGER *serial = NULL;
168 X509_EXTENSION *ext;
169 X509 *cert;
170 AUTHORITY_KEYID *akeyid = NULL;
171
172 for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
173 cnf = sk_CONF_VALUE_value(values, i);
174 if (!strcmp(cnf->name, "keyid")) {
175 keyid = 1;
176 if (cnf->value && !strcmp(cnf->value, "always"))
177 keyid = 2;
178 } else if (!strcmp(cnf->name, "issuer")) {
179 issuer = 1;
180 if (cnf->value && !strcmp(cnf->value, "always"))
181 issuer = 2;
182 } else {
183 X509V3error(X509V3_R_UNKNOWN_OPTION);
184 ERR_asprintf_error_data("name=%s", cnf->name);
185 return NULL;
186 }
187 }
188
189 if (!ctx || !ctx->issuer_cert) {
190 if (ctx && (ctx->flags == CTX_TEST))
191 return AUTHORITY_KEYID_new();
192 X509V3error(X509V3_R_NO_ISSUER_CERTIFICATE);
193 return NULL;
194 }
195
196 cert = ctx->issuer_cert;
197
198 if (keyid) {
199 i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
200 if ((i >= 0) && (ext = X509_get_ext(cert, i)))
201 ikeyid = X509V3_EXT_d2i(ext);
202 if (keyid == 2 && !ikeyid) {
203 X509V3error(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
204 return NULL;
205 }
206 }
207
208 if ((issuer && !ikeyid) || (issuer == 2)) {
209 isname = X509_NAME_dup(X509_get_issuer_name(cert));
210 serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert));
211 if (!isname || !serial) {
212 X509V3error(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
213 goto err;
214 }
215 }
216
217 if (!(akeyid = AUTHORITY_KEYID_new()))
218 goto err;
219
220 if (isname) {
221 if (!(gens = sk_GENERAL_NAME_new_null()) ||
222 !(gen = GENERAL_NAME_new()) ||
223 !sk_GENERAL_NAME_push(gens, gen)) {
224 X509V3error(ERR_R_MALLOC_FAILURE);
225 goto err;
226 }
227 gen->type = GEN_DIRNAME;
228 gen->d.dirn = isname;
229 }
230
231 akeyid->issuer = gens;
232 akeyid->serial = serial;
233 akeyid->keyid = ikeyid;
234
235 return akeyid;
236
237 err:
238 AUTHORITY_KEYID_free(akeyid);
239 GENERAL_NAME_free(gen);
240 sk_GENERAL_NAME_free(gens);
241 X509_NAME_free(isname);
242 ASN1_INTEGER_free(serial);
243 ASN1_OCTET_STRING_free(ikeyid);
244 return NULL;
245}
diff --git a/src/lib/libcrypto/x509/x509_akeya.c b/src/lib/libcrypto/x509/x509_akeya.c
deleted file mode 100644
index e816e6b613..0000000000
--- a/src/lib/libcrypto/x509/x509_akeya.c
+++ /dev/null
@@ -1,129 +0,0 @@
1/* $OpenBSD: x509_akeya.c,v 1.4 2024/07/08 14:47:44 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/asn1t.h>
63#include <openssl/conf.h>
64#include <openssl/x509v3.h>
65
66static const ASN1_TEMPLATE AUTHORITY_KEYID_seq_tt[] = {
67 {
68 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
69 .tag = 0,
70 .offset = offsetof(AUTHORITY_KEYID, keyid),
71 .field_name = "keyid",
72 .item = &ASN1_OCTET_STRING_it,
73 },
74 {
75 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
76 .tag = 1,
77 .offset = offsetof(AUTHORITY_KEYID, issuer),
78 .field_name = "issuer",
79 .item = &GENERAL_NAME_it,
80 },
81 {
82 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
83 .tag = 2,
84 .offset = offsetof(AUTHORITY_KEYID, serial),
85 .field_name = "serial",
86 .item = &ASN1_INTEGER_it,
87 },
88};
89
90const ASN1_ITEM AUTHORITY_KEYID_it = {
91 .itype = ASN1_ITYPE_SEQUENCE,
92 .utype = V_ASN1_SEQUENCE,
93 .templates = AUTHORITY_KEYID_seq_tt,
94 .tcount = sizeof(AUTHORITY_KEYID_seq_tt) / sizeof(ASN1_TEMPLATE),
95 .funcs = NULL,
96 .size = sizeof(AUTHORITY_KEYID),
97 .sname = "AUTHORITY_KEYID",
98};
99LCRYPTO_ALIAS(AUTHORITY_KEYID_it);
100
101
102AUTHORITY_KEYID *
103d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, const unsigned char **in, long len)
104{
105 return (AUTHORITY_KEYID *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
106 &AUTHORITY_KEYID_it);
107}
108LCRYPTO_ALIAS(d2i_AUTHORITY_KEYID);
109
110int
111i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out)
112{
113 return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_KEYID_it);
114}
115LCRYPTO_ALIAS(i2d_AUTHORITY_KEYID);
116
117AUTHORITY_KEYID *
118AUTHORITY_KEYID_new(void)
119{
120 return (AUTHORITY_KEYID *)ASN1_item_new(&AUTHORITY_KEYID_it);
121}
122LCRYPTO_ALIAS(AUTHORITY_KEYID_new);
123
124void
125AUTHORITY_KEYID_free(AUTHORITY_KEYID *a)
126{
127 ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_KEYID_it);
128}
129LCRYPTO_ALIAS(AUTHORITY_KEYID_free);
diff --git a/src/lib/libcrypto/x509/x509_alt.c b/src/lib/libcrypto/x509/x509_alt.c
deleted file mode 100644
index 34734a55bd..0000000000
--- a/src/lib/libcrypto/x509/x509_alt.c
+++ /dev/null
@@ -1,799 +0,0 @@
1/* $OpenBSD: x509_alt.c,v 1.19 2025/03/06 07:20:01 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2003 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/conf.h>
63#include <openssl/err.h>
64#include <openssl/x509v3.h>
65
66#include "x509_internal.h"
67
68static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
69 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
70static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
71 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
72static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
73static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
74static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
75static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
76
77static const X509V3_EXT_METHOD x509v3_ext_subject_alt_name = {
78 .ext_nid = NID_subject_alt_name,
79 .ext_flags = 0,
80 .it = &GENERAL_NAMES_it,
81 .ext_new = NULL,
82 .ext_free = NULL,
83 .d2i = NULL,
84 .i2d = NULL,
85 .i2s = NULL,
86 .s2i = NULL,
87 .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
88 .v2i = (X509V3_EXT_V2I)v2i_subject_alt,
89 .i2r = NULL,
90 .r2i = NULL,
91 .usr_data = NULL,
92};
93
94const X509V3_EXT_METHOD *
95x509v3_ext_method_subject_alt_name(void)
96{
97 return &x509v3_ext_subject_alt_name;
98}
99
100static const X509V3_EXT_METHOD x509v3_ext_issuer_alt_name = {
101 .ext_nid = NID_issuer_alt_name,
102 .ext_flags = 0,
103 .it = &GENERAL_NAMES_it,
104 .ext_new = NULL,
105 .ext_free = NULL,
106 .d2i = NULL,
107 .i2d = NULL,
108 .i2s = NULL,
109 .s2i = NULL,
110 .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
111 .v2i = (X509V3_EXT_V2I)v2i_issuer_alt,
112 .i2r = NULL,
113 .r2i = NULL,
114 .usr_data = NULL,
115};
116
117const X509V3_EXT_METHOD *
118x509v3_ext_method_issuer_alt_name(void)
119{
120 return &x509v3_ext_issuer_alt_name;
121}
122
123static const X509V3_EXT_METHOD x509v3_ext_certificate_issuer = {
124 .ext_nid = NID_certificate_issuer,
125 .ext_flags = 0,
126 .it = &GENERAL_NAMES_it,
127 .ext_new = NULL,
128 .ext_free = NULL,
129 .d2i = NULL,
130 .i2d = NULL,
131 .i2s = NULL,
132 .s2i = NULL,
133 .i2v = (X509V3_EXT_I2V)i2v_GENERAL_NAMES,
134 .v2i = NULL,
135 .i2r = NULL,
136 .r2i = NULL,
137 .usr_data = NULL,
138};
139
140const X509V3_EXT_METHOD *
141x509v3_ext_method_certificate_issuer(void)
142{
143 return &x509v3_ext_certificate_issuer;
144}
145
146STACK_OF(CONF_VALUE) *
147i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, GENERAL_NAMES *gens,
148 STACK_OF(CONF_VALUE) *ret)
149{
150 STACK_OF(CONF_VALUE) *free_ret = NULL;
151 GENERAL_NAME *gen;
152 int i;
153
154 if (ret == NULL) {
155 if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
156 return NULL;
157 }
158
159 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
160 if ((gen = sk_GENERAL_NAME_value(gens, i)) == NULL)
161 goto err;
162 if ((ret = i2v_GENERAL_NAME(method, gen, ret)) == NULL)
163 goto err;
164 }
165
166 return ret;
167
168 err:
169 sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
170
171 return NULL;
172}
173LCRYPTO_ALIAS(i2v_GENERAL_NAMES);
174
175STACK_OF(CONF_VALUE) *
176i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen,
177 STACK_OF(CONF_VALUE) *ret)
178{
179 STACK_OF(CONF_VALUE) *free_ret = NULL;
180 unsigned char *p;
181 char oline[256], htmp[5];
182 int i;
183
184 if (ret == NULL) {
185 if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
186 return NULL;
187 }
188
189 switch (gen->type) {
190 case GEN_OTHERNAME:
191 if (!X509V3_add_value("othername", "<unsupported>", &ret))
192 goto err;
193 break;
194
195 case GEN_X400:
196 if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
197 goto err;
198 break;
199
200 case GEN_EDIPARTY:
201 if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret))
202 goto err;
203 break;
204
205 case GEN_EMAIL:
206 if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret))
207 goto err;
208 break;
209
210 case GEN_DNS:
211 if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret))
212 goto err;
213 break;
214
215 case GEN_URI:
216 if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret))
217 goto err;
218 break;
219
220 case GEN_DIRNAME:
221 if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL)
222 goto err;
223 if (!X509V3_add_value("DirName", oline, &ret))
224 goto err;
225 break;
226
227 case GEN_IPADD: /* XXX */
228 p = gen->d.ip->data;
229 if (gen->d.ip->length == 4)
230 (void) snprintf(oline, sizeof oline,
231 "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
232 else if (gen->d.ip->length == 16) {
233 oline[0] = 0;
234 for (i = 0; i < 8; i++) {
235 (void) snprintf(htmp, sizeof htmp,
236 "%X", p[0] << 8 | p[1]);
237 p += 2;
238 strlcat(oline, htmp, sizeof(oline));
239 if (i != 7)
240 strlcat(oline, ":", sizeof(oline));
241 }
242 } else {
243 if (!X509V3_add_value("IP Address", "<invalid>", &ret))
244 goto err;
245 break;
246 }
247 if (!X509V3_add_value("IP Address", oline, &ret))
248 goto err;
249 break;
250
251 case GEN_RID:
252 if (!i2t_ASN1_OBJECT(oline, 256, gen->d.rid))
253 goto err;
254 if (!X509V3_add_value("Registered ID", oline, &ret))
255 goto err;
256 break;
257 }
258
259 return ret;
260
261 err:
262 sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
263
264 return NULL;
265}
266LCRYPTO_ALIAS(i2v_GENERAL_NAME);
267
268int
269GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
270{
271 unsigned char *p;
272 int i;
273
274 switch (gen->type) {
275 case GEN_OTHERNAME:
276 BIO_printf(out, "othername:<unsupported>");
277 break;
278
279 case GEN_X400:
280 BIO_printf(out, "X400Name:<unsupported>");
281 break;
282
283 case GEN_EDIPARTY:
284 /* Maybe fix this: it is supported now */
285 BIO_printf(out, "EdiPartyName:<unsupported>");
286 break;
287
288 case GEN_EMAIL:
289 BIO_printf(out, "email:%.*s", gen->d.ia5->length,
290 gen->d.ia5->data);
291 break;
292
293 case GEN_DNS:
294 BIO_printf(out, "DNS:%.*s", gen->d.ia5->length,
295 gen->d.ia5->data);
296 break;
297
298 case GEN_URI:
299 BIO_printf(out, "URI:%.*s", gen->d.ia5->length,
300 gen->d.ia5->data);
301 break;
302
303 case GEN_DIRNAME:
304 BIO_printf(out, "DirName: ");
305 X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
306 break;
307
308 case GEN_IPADD:
309 p = gen->d.ip->data;
310 if (gen->d.ip->length == 4)
311 BIO_printf(out, "IP Address:%d.%d.%d.%d",
312 p[0], p[1], p[2], p[3]);
313 else if (gen->d.ip->length == 16) {
314 BIO_printf(out, "IP Address");
315 for (i = 0; i < 8; i++) {
316 BIO_printf(out, ":%X", p[0] << 8 | p[1]);
317 p += 2;
318 }
319 BIO_puts(out, "\n");
320 } else {
321 BIO_printf(out, "IP Address:<invalid>");
322 break;
323 }
324 break;
325
326 case GEN_RID:
327 BIO_printf(out, "Registered ID");
328 i2a_ASN1_OBJECT(out, gen->d.rid);
329 break;
330 }
331 return 1;
332}
333LCRYPTO_ALIAS(GENERAL_NAME_print);
334
335static GENERAL_NAMES *
336v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
337 STACK_OF(CONF_VALUE) *nval)
338{
339 GENERAL_NAMES *gens = NULL;
340 CONF_VALUE *cnf;
341 int i;
342
343 if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
344 X509V3error(ERR_R_MALLOC_FAILURE);
345 return NULL;
346 }
347 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
348 cnf = sk_CONF_VALUE_value(nval, i);
349 if (name_cmp(cnf->name, "issuer") == 0 && cnf->value != NULL &&
350 strcmp(cnf->value, "copy") == 0) {
351 if (!copy_issuer(ctx, gens))
352 goto err;
353 } else {
354 GENERAL_NAME *gen;
355 if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
356 goto err;
357 if (sk_GENERAL_NAME_push(gens, gen) == 0) {
358 GENERAL_NAME_free(gen);
359 goto err;
360 }
361 }
362 }
363 return gens;
364
365err:
366 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
367 return NULL;
368}
369
370/* Append subject altname of issuer to issuer alt name of subject */
371
372static int
373copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
374{
375 GENERAL_NAMES *ialt = NULL;
376 GENERAL_NAME *gen = NULL;
377 X509_EXTENSION *ext;
378 int i;
379 int ret = 0;
380
381 if (ctx && (ctx->flags == CTX_TEST))
382 return 1;
383 if (!ctx || !ctx->issuer_cert) {
384 X509V3error(X509V3_R_NO_ISSUER_DETAILS);
385 goto err;
386 }
387 i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
388 if (i < 0)
389 return 1;
390 if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
391 !(ialt = X509V3_EXT_d2i(ext))) {
392 X509V3error(X509V3_R_ISSUER_DECODE_ERROR);
393 goto err;
394 }
395
396 for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
397 GENERAL_NAME *val = sk_GENERAL_NAME_value(ialt, i);
398
399 if ((gen = GENERAL_NAME_dup(val)) == NULL)
400 goto err;
401 if (!sk_GENERAL_NAME_push(gens, gen)) {
402 X509V3error(ERR_R_MALLOC_FAILURE);
403 goto err;
404 }
405 gen = NULL;
406 }
407
408 ret = 1;
409
410 err:
411 sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
412 GENERAL_NAME_free(gen);
413
414 return ret;
415}
416
417static GENERAL_NAMES *
418v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
419 STACK_OF(CONF_VALUE) *nval)
420{
421 GENERAL_NAMES *gens = NULL;
422 CONF_VALUE *cnf;
423 int i;
424
425 if (!(gens = sk_GENERAL_NAME_new_null())) {
426 X509V3error(ERR_R_MALLOC_FAILURE);
427 return NULL;
428 }
429 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
430 cnf = sk_CONF_VALUE_value(nval, i);
431 if (!name_cmp(cnf->name, "email") && cnf->value &&
432 !strcmp(cnf->value, "copy")) {
433 if (!copy_email(ctx, gens, 0))
434 goto err;
435 } else if (!name_cmp(cnf->name, "email") && cnf->value &&
436 !strcmp(cnf->value, "move")) {
437 if (!copy_email(ctx, gens, 1))
438 goto err;
439 } else {
440 GENERAL_NAME *gen;
441 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
442 goto err;
443 if (sk_GENERAL_NAME_push(gens, gen) == 0) {
444 GENERAL_NAME_free(gen);
445 goto err;
446 }
447 }
448 }
449 return gens;
450
451err:
452 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
453 return NULL;
454}
455
456/* Copy any email addresses in a certificate or request to
457 * GENERAL_NAMES
458 */
459
460static int
461copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
462{
463 X509_NAME *nm;
464 ASN1_IA5STRING *email = NULL;
465 X509_NAME_ENTRY *ne;
466 GENERAL_NAME *gen = NULL;
467 int i;
468
469 if (ctx != NULL && ctx->flags == CTX_TEST)
470 return 1;
471 if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
472 X509V3error(X509V3_R_NO_SUBJECT_DETAILS);
473 goto err;
474 }
475 /* Find the subject name */
476 if (ctx->subject_cert)
477 nm = X509_get_subject_name(ctx->subject_cert);
478 else
479 nm = X509_REQ_get_subject_name(ctx->subject_req);
480
481 /* Now add any email address(es) to STACK */
482 i = -1;
483 while ((i = X509_NAME_get_index_by_NID(nm,
484 NID_pkcs9_emailAddress, i)) >= 0) {
485 ne = X509_NAME_get_entry(nm, i);
486 email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
487 if (move_p) {
488 X509_NAME_delete_entry(nm, i);
489 X509_NAME_ENTRY_free(ne);
490 i--;
491 }
492 if (!email || !(gen = GENERAL_NAME_new())) {
493 X509V3error(ERR_R_MALLOC_FAILURE);
494 goto err;
495 }
496 gen->d.ia5 = email;
497 email = NULL;
498 gen->type = GEN_EMAIL;
499 if (!sk_GENERAL_NAME_push(gens, gen)) {
500 X509V3error(ERR_R_MALLOC_FAILURE);
501 goto err;
502 }
503 gen = NULL;
504 }
505
506 return 1;
507
508err:
509 GENERAL_NAME_free(gen);
510 ASN1_IA5STRING_free(email);
511 return 0;
512}
513
514GENERAL_NAMES *
515v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
516 STACK_OF(CONF_VALUE) *nval)
517{
518 GENERAL_NAME *gen;
519 GENERAL_NAMES *gens = NULL;
520 CONF_VALUE *cnf;
521 int i;
522
523 if (!(gens = sk_GENERAL_NAME_new_null())) {
524 X509V3error(ERR_R_MALLOC_FAILURE);
525 return NULL;
526 }
527 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
528 cnf = sk_CONF_VALUE_value(nval, i);
529 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
530 goto err;
531 if (sk_GENERAL_NAME_push(gens, gen) == 0) {
532 GENERAL_NAME_free(gen);
533 goto err;
534 }
535 }
536 return gens;
537
538err:
539 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
540 return NULL;
541}
542LCRYPTO_ALIAS(v2i_GENERAL_NAMES);
543
544GENERAL_NAME *
545v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
546 CONF_VALUE *cnf)
547{
548 return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
549}
550LCRYPTO_ALIAS(v2i_GENERAL_NAME);
551
552GENERAL_NAME *
553a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
554 X509V3_CTX *ctx, int gen_type, const char *value, int is_nc)
555{
556 char is_string = 0;
557 GENERAL_NAME *gen = NULL;
558
559 if (!value) {
560 X509V3error(X509V3_R_MISSING_VALUE);
561 return NULL;
562 }
563
564 if (out)
565 gen = out;
566 else {
567 gen = GENERAL_NAME_new();
568 if (gen == NULL) {
569 X509V3error(ERR_R_MALLOC_FAILURE);
570 return NULL;
571 }
572 }
573
574 switch (gen_type) {
575 case GEN_URI:
576 case GEN_EMAIL:
577 case GEN_DNS:
578 is_string = 1;
579 break;
580
581 case GEN_RID:
582 {
583 ASN1_OBJECT *obj;
584 if (!(obj = OBJ_txt2obj(value, 0))) {
585 X509V3error(X509V3_R_BAD_OBJECT);
586 ERR_asprintf_error_data("value=%s", value);
587 goto err;
588 }
589 gen->d.rid = obj;
590 }
591 break;
592
593 case GEN_IPADD:
594 if (is_nc)
595 gen->d.ip = a2i_IPADDRESS_NC(value);
596 else
597 gen->d.ip = a2i_IPADDRESS(value);
598 if (gen->d.ip == NULL) {
599 X509V3error(X509V3_R_BAD_IP_ADDRESS);
600 ERR_asprintf_error_data("value=%s", value);
601 goto err;
602 }
603 break;
604
605 case GEN_DIRNAME:
606 if (!do_dirname(gen, value, ctx)) {
607 X509V3error(X509V3_R_DIRNAME_ERROR);
608 goto err;
609 }
610 break;
611
612 case GEN_OTHERNAME:
613 if (!do_othername(gen, value, ctx)) {
614 X509V3error(X509V3_R_OTHERNAME_ERROR);
615 goto err;
616 }
617 break;
618
619 default:
620 X509V3error(X509V3_R_UNSUPPORTED_TYPE);
621 goto err;
622 }
623
624 if (is_string) {
625 if (!(gen->d.ia5 = ASN1_IA5STRING_new()) ||
626 !ASN1_STRING_set(gen->d.ia5, value, strlen(value))) {
627 X509V3error(ERR_R_MALLOC_FAILURE);
628 goto err;
629 }
630 }
631
632 gen->type = gen_type;
633
634 return gen;
635
636err:
637 if (out == NULL)
638 GENERAL_NAME_free(gen);
639 return NULL;
640}
641LCRYPTO_ALIAS(a2i_GENERAL_NAME);
642
643GENERAL_NAME *
644v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method,
645 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
646{
647 uint8_t *bytes = NULL;
648 char *name, *value;
649 GENERAL_NAME *ret;
650 size_t len = 0;
651 int type;
652 CBS cbs;
653
654 name = cnf->name;
655 value = cnf->value;
656
657 if (!value) {
658 X509V3error(X509V3_R_MISSING_VALUE);
659 return NULL;
660 }
661
662 if (!name_cmp(name, "email"))
663 type = GEN_EMAIL;
664 else if (!name_cmp(name, "URI"))
665 type = GEN_URI;
666 else if (!name_cmp(name, "DNS"))
667 type = GEN_DNS;
668 else if (!name_cmp(name, "RID"))
669 type = GEN_RID;
670 else if (!name_cmp(name, "IP"))
671 type = GEN_IPADD;
672 else if (!name_cmp(name, "dirName"))
673 type = GEN_DIRNAME;
674 else if (!name_cmp(name, "otherName"))
675 type = GEN_OTHERNAME;
676 else {
677 X509V3error(X509V3_R_UNSUPPORTED_OPTION);
678 ERR_asprintf_error_data("name=%s", name);
679 return NULL;
680 }
681
682 ret = a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
683 if (ret == NULL)
684 return NULL;
685
686 /*
687 * Validate what we have for sanity.
688 */
689
690 if (is_nc) {
691 struct x509_constraints_name *constraints_name = NULL;
692
693 if (!x509_constraints_validate(ret, &constraints_name, NULL)) {
694 X509V3error(X509V3_R_BAD_OBJECT);
695 ERR_asprintf_error_data("name=%s", name);
696 goto err;
697 }
698 x509_constraints_name_free(constraints_name);
699 return ret;
700 }
701
702 type = x509_constraints_general_to_bytes(ret, &bytes, &len);
703 CBS_init(&cbs, bytes, len);
704 switch (type) {
705 case GEN_DNS:
706 if (!x509_constraints_valid_sandns(&cbs)) {
707 X509V3error(X509V3_R_BAD_OBJECT);
708 ERR_asprintf_error_data("name=%s value='%.*s'", name,
709 (int)len, bytes);
710 goto err;
711 }
712 break;
713 case GEN_URI:
714 if (!x509_constraints_uri_host(bytes, len, NULL)) {
715 X509V3error(X509V3_R_BAD_OBJECT);
716 ERR_asprintf_error_data("name=%s value='%.*s'", name,
717 (int)len, bytes);
718 goto err;
719 }
720 break;
721 case GEN_EMAIL:
722 if (!x509_constraints_parse_mailbox(&cbs, NULL)) {
723 X509V3error(X509V3_R_BAD_OBJECT);
724 ERR_asprintf_error_data("name=%s value='%.*s'", name,
725 (int)len, bytes);
726 goto err;
727 }
728 break;
729 case GEN_IPADD:
730 if (len != 4 && len != 16) {
731 X509V3error(X509V3_R_BAD_IP_ADDRESS);
732 ERR_asprintf_error_data("name=%s len=%zu", name, len);
733 goto err;
734 }
735 break;
736 default:
737 break;
738 }
739 return ret;
740 err:
741 if (out == NULL)
742 GENERAL_NAME_free(ret);
743 return NULL;
744}
745LCRYPTO_ALIAS(v2i_GENERAL_NAME_ex);
746
747static int
748do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
749{
750 char *objtmp = NULL, *p;
751 int objlen;
752
753 if (!(p = strchr(value, ';')))
754 return 0;
755 if (!(gen->d.otherName = OTHERNAME_new()))
756 return 0;
757 /* Free this up because we will overwrite it.
758 * no need to free type_id because it is static
759 */
760 ASN1_TYPE_free(gen->d.otherName->value);
761 if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)))
762 return 0;
763 objlen = p - value;
764 objtmp = malloc(objlen + 1);
765 if (objtmp) {
766 strlcpy(objtmp, value, objlen + 1);
767 gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
768 free(objtmp);
769 } else
770 gen->d.otherName->type_id = NULL;
771 if (!gen->d.otherName->type_id)
772 return 0;
773 return 1;
774}
775
776static int
777do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
778{
779 int ret;
780 STACK_OF(CONF_VALUE) *sk;
781 X509_NAME *nm;
782
783 if (!(nm = X509_NAME_new()))
784 return 0;
785 sk = X509V3_get0_section(ctx, value);
786 if (!sk) {
787 X509V3error(X509V3_R_SECTION_NOT_FOUND);
788 ERR_asprintf_error_data("section=%s", value);
789 X509_NAME_free(nm);
790 return 0;
791 }
792 /* FIXME: should allow other character types... */
793 ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
794 if (!ret)
795 X509_NAME_free(nm);
796 gen->d.dirn = nm;
797
798 return ret;
799}
diff --git a/src/lib/libcrypto/x509/x509_asid.c b/src/lib/libcrypto/x509/x509_asid.c
deleted file mode 100644
index 40ee201a9f..0000000000
--- a/src/lib/libcrypto/x509/x509_asid.c
+++ /dev/null
@@ -1,1255 +0,0 @@
1/* $OpenBSD: x509_asid.c,v 1.45 2024/07/13 15:08:58 tb Exp $ */
2/*
3 * Contributed to the OpenSSL Project by the American Registry for
4 * Internet Numbers ("ARIN").
5 */
6/* ====================================================================
7 * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 */
58
59/*
60 * Implementation of RFC 3779 section 3.2.
61 */
62
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66
67#include <openssl/asn1.h>
68#include <openssl/asn1t.h>
69#include <openssl/bn.h>
70#include <openssl/conf.h>
71#include <openssl/err.h>
72#include <openssl/x509.h>
73#include <openssl/x509v3.h>
74
75#include "x509_local.h"
76
77#ifndef OPENSSL_NO_RFC3779
78
79static const ASN1_TEMPLATE ASRange_seq_tt[] = {
80 {
81 .flags = 0,
82 .tag = 0,
83 .offset = offsetof(ASRange, min),
84 .field_name = "min",
85 .item = &ASN1_INTEGER_it,
86 },
87 {
88 .flags = 0,
89 .tag = 0,
90 .offset = offsetof(ASRange, max),
91 .field_name = "max",
92 .item = &ASN1_INTEGER_it,
93 },
94};
95
96const ASN1_ITEM ASRange_it = {
97 .itype = ASN1_ITYPE_SEQUENCE,
98 .utype = V_ASN1_SEQUENCE,
99 .templates = ASRange_seq_tt,
100 .tcount = sizeof(ASRange_seq_tt) / sizeof(ASN1_TEMPLATE),
101 .funcs = NULL,
102 .size = sizeof(ASRange),
103 .sname = "ASRange",
104};
105LCRYPTO_ALIAS(ASRange_it);
106
107static const ASN1_TEMPLATE ASIdOrRange_ch_tt[] = {
108 {
109 .flags = 0,
110 .tag = 0,
111 .offset = offsetof(ASIdOrRange, u.id),
112 .field_name = "u.id",
113 .item = &ASN1_INTEGER_it,
114 },
115 {
116 .flags = 0,
117 .tag = 0,
118 .offset = offsetof(ASIdOrRange, u.range),
119 .field_name = "u.range",
120 .item = &ASRange_it,
121 },
122};
123
124const ASN1_ITEM ASIdOrRange_it = {
125 .itype = ASN1_ITYPE_CHOICE,
126 .utype = offsetof(ASIdOrRange, type),
127 .templates = ASIdOrRange_ch_tt,
128 .tcount = sizeof(ASIdOrRange_ch_tt) / sizeof(ASN1_TEMPLATE),
129 .funcs = NULL,
130 .size = sizeof(ASIdOrRange),
131 .sname = "ASIdOrRange",
132};
133LCRYPTO_ALIAS(ASIdOrRange_it);
134
135static const ASN1_TEMPLATE ASIdentifierChoice_ch_tt[] = {
136 {
137 .flags = 0,
138 .tag = 0,
139 .offset = offsetof(ASIdentifierChoice, u.inherit),
140 .field_name = "u.inherit",
141 .item = &ASN1_NULL_it,
142 },
143 {
144 .flags = ASN1_TFLG_SEQUENCE_OF,
145 .tag = 0,
146 .offset = offsetof(ASIdentifierChoice, u.asIdsOrRanges),
147 .field_name = "u.asIdsOrRanges",
148 .item = &ASIdOrRange_it,
149 },
150};
151
152const ASN1_ITEM ASIdentifierChoice_it = {
153 .itype = ASN1_ITYPE_CHOICE,
154 .utype = offsetof(ASIdentifierChoice, type),
155 .templates = ASIdentifierChoice_ch_tt,
156 .tcount = sizeof(ASIdentifierChoice_ch_tt) / sizeof(ASN1_TEMPLATE),
157 .funcs = NULL,
158 .size = sizeof(ASIdentifierChoice),
159 .sname = "ASIdentifierChoice",
160};
161LCRYPTO_ALIAS(ASIdentifierChoice_it);
162
163static const ASN1_TEMPLATE ASIdentifiers_seq_tt[] = {
164 {
165 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
166 .tag = 0,
167 .offset = offsetof(ASIdentifiers, asnum),
168 .field_name = "asnum",
169 .item = &ASIdentifierChoice_it,
170 },
171 {
172 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
173 .tag = 1,
174 .offset = offsetof(ASIdentifiers, rdi),
175 .field_name = "rdi",
176 .item = &ASIdentifierChoice_it,
177 },
178};
179
180const ASN1_ITEM ASIdentifiers_it = {
181 .itype = ASN1_ITYPE_SEQUENCE,
182 .utype = V_ASN1_SEQUENCE,
183 .templates = ASIdentifiers_seq_tt,
184 .tcount = sizeof(ASIdentifiers_seq_tt) / sizeof(ASN1_TEMPLATE),
185 .funcs = NULL,
186 .size = sizeof(ASIdentifiers),
187 .sname = "ASIdentifiers",
188};
189LCRYPTO_ALIAS(ASIdentifiers_it);
190
191ASRange *
192d2i_ASRange(ASRange **a, const unsigned char **in, long len)
193{
194 return (ASRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
195 &ASRange_it);
196}
197LCRYPTO_ALIAS(d2i_ASRange);
198
199int
200i2d_ASRange(ASRange *a, unsigned char **out)
201{
202 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASRange_it);
203}
204LCRYPTO_ALIAS(i2d_ASRange);
205
206ASRange *
207ASRange_new(void)
208{
209 return (ASRange *)ASN1_item_new(&ASRange_it);
210}
211LCRYPTO_ALIAS(ASRange_new);
212
213void
214ASRange_free(ASRange *a)
215{
216 ASN1_item_free((ASN1_VALUE *)a, &ASRange_it);
217}
218LCRYPTO_ALIAS(ASRange_free);
219
220ASIdOrRange *
221d2i_ASIdOrRange(ASIdOrRange **a, const unsigned char **in, long len)
222{
223 return (ASIdOrRange *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
224 &ASIdOrRange_it);
225}
226LCRYPTO_ALIAS(d2i_ASIdOrRange);
227
228int
229i2d_ASIdOrRange(ASIdOrRange *a, unsigned char **out)
230{
231 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdOrRange_it);
232}
233LCRYPTO_ALIAS(i2d_ASIdOrRange);
234
235ASIdOrRange *
236ASIdOrRange_new(void)
237{
238 return (ASIdOrRange *)ASN1_item_new(&ASIdOrRange_it);
239}
240LCRYPTO_ALIAS(ASIdOrRange_new);
241
242void
243ASIdOrRange_free(ASIdOrRange *a)
244{
245 ASN1_item_free((ASN1_VALUE *)a, &ASIdOrRange_it);
246}
247LCRYPTO_ALIAS(ASIdOrRange_free);
248
249ASIdentifierChoice *
250d2i_ASIdentifierChoice(ASIdentifierChoice **a, const unsigned char **in,
251 long len)
252{
253 return (ASIdentifierChoice *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
254 &ASIdentifierChoice_it);
255}
256LCRYPTO_ALIAS(d2i_ASIdentifierChoice);
257
258int
259i2d_ASIdentifierChoice(ASIdentifierChoice *a, unsigned char **out)
260{
261 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifierChoice_it);
262}
263LCRYPTO_ALIAS(i2d_ASIdentifierChoice);
264
265ASIdentifierChoice *
266ASIdentifierChoice_new(void)
267{
268 return (ASIdentifierChoice *)ASN1_item_new(&ASIdentifierChoice_it);
269}
270LCRYPTO_ALIAS(ASIdentifierChoice_new);
271
272void
273ASIdentifierChoice_free(ASIdentifierChoice *a)
274{
275 ASN1_item_free((ASN1_VALUE *)a, &ASIdentifierChoice_it);
276}
277LCRYPTO_ALIAS(ASIdentifierChoice_free);
278
279ASIdentifiers *
280d2i_ASIdentifiers(ASIdentifiers **a, const unsigned char **in, long len)
281{
282 return (ASIdentifiers *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
283 &ASIdentifiers_it);
284}
285LCRYPTO_ALIAS(d2i_ASIdentifiers);
286
287int
288i2d_ASIdentifiers(ASIdentifiers *a, unsigned char **out)
289{
290 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASIdentifiers_it);
291}
292LCRYPTO_ALIAS(i2d_ASIdentifiers);
293
294ASIdentifiers *
295ASIdentifiers_new(void)
296{
297 return (ASIdentifiers *)ASN1_item_new(&ASIdentifiers_it);
298}
299LCRYPTO_ALIAS(ASIdentifiers_new);
300
301void
302ASIdentifiers_free(ASIdentifiers *a)
303{
304 ASN1_item_free((ASN1_VALUE *)a, &ASIdentifiers_it);
305}
306LCRYPTO_ALIAS(ASIdentifiers_free);
307
308/*
309 * i2r method for an ASIdentifierChoice.
310 */
311static int
312i2r_ASIdentifierChoice(BIO *out, ASIdentifierChoice *choice, int indent,
313 const char *msg)
314{
315 int i;
316 char *s;
317 if (choice == NULL)
318 return 1;
319 BIO_printf(out, "%*s%s:\n", indent, "", msg);
320 switch (choice->type) {
321 case ASIdentifierChoice_inherit:
322 BIO_printf(out, "%*sinherit\n", indent + 2, "");
323 break;
324 case ASIdentifierChoice_asIdsOrRanges:
325 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges);
326 i++) {
327 ASIdOrRange *aor =
328 sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
329 switch (aor->type) {
330 case ASIdOrRange_id:
331 if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) ==
332 NULL)
333 return 0;
334 BIO_printf(out, "%*s%s\n", indent + 2, "", s);
335 free(s);
336 break;
337 case ASIdOrRange_range:
338 if ((s = i2s_ASN1_INTEGER(NULL,
339 aor->u.range->min)) == NULL)
340 return 0;
341 BIO_printf(out, "%*s%s-", indent + 2, "", s);
342 free(s);
343 if ((s = i2s_ASN1_INTEGER(NULL,
344 aor->u.range->max)) == NULL)
345 return 0;
346 BIO_printf(out, "%s\n", s);
347 free(s);
348 break;
349 default:
350 return 0;
351 }
352 }
353 break;
354 default:
355 return 0;
356 }
357 return 1;
358}
359
360/*
361 * i2r method for an ASIdentifier extension.
362 */
363static int
364i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, void *ext, BIO *out,
365 int indent)
366{
367 ASIdentifiers *asid = ext;
368 return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
369 "Autonomous System Numbers") &&
370 i2r_ASIdentifierChoice(out, asid->rdi, indent,
371 "Routing Domain Identifiers"));
372}
373
374/*
375 * Sort comparison function for a sequence of ASIdOrRange elements.
376 */
377static int
378ASIdOrRange_cmp(const ASIdOrRange *const *a_, const ASIdOrRange *const *b_)
379{
380 const ASIdOrRange *a = *a_, *b = *b_;
381
382 /* XXX: these asserts need to be replaced */
383 OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
384 (a->type == ASIdOrRange_range && a->u.range != NULL &&
385 a->u.range->min != NULL && a->u.range->max != NULL));
386
387 OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
388 (b->type == ASIdOrRange_range && b->u.range != NULL &&
389 b->u.range->min != NULL && b->u.range->max != NULL));
390
391 if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
392 return ASN1_INTEGER_cmp(a->u.id, b->u.id);
393
394 if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
395 int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
396 return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max,
397 b->u.range->max);
398 }
399
400 if (a->type == ASIdOrRange_id)
401 return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
402 else
403 return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
404}
405
406/*
407 * Add an inherit element.
408 */
409int
410X509v3_asid_add_inherit(ASIdentifiers *asid, int which)
411{
412 ASIdentifierChoice **choice;
413 ASIdentifierChoice *aic = NULL;
414 int ret = 0;
415
416 if (asid == NULL)
417 goto err;
418
419 switch (which) {
420 case V3_ASID_ASNUM:
421 choice = &asid->asnum;
422 break;
423 case V3_ASID_RDI:
424 choice = &asid->rdi;
425 break;
426 default:
427 goto err;
428 }
429
430 if (*choice != NULL) {
431 if ((*choice)->type != ASIdentifierChoice_inherit)
432 goto err;
433 } else {
434 if ((aic = ASIdentifierChoice_new()) == NULL)
435 goto err;
436 if ((aic->u.inherit = ASN1_NULL_new()) == NULL)
437 goto err;
438 aic->type = ASIdentifierChoice_inherit;
439
440 *choice = aic;
441 aic = NULL;
442 }
443
444 ret = 1;
445
446 err:
447 ASIdentifierChoice_free(aic);
448
449 return ret;
450}
451LCRYPTO_ALIAS(X509v3_asid_add_inherit);
452
453static int
454ASIdOrRanges_add_id_or_range(ASIdOrRanges *aors, ASN1_INTEGER *min,
455 ASN1_INTEGER *max)
456{
457 ASIdOrRange *aor = NULL;
458 ASRange *asr = NULL;
459 int ret = 0;
460
461 /* Preallocate since we must not fail after sk_ASIdOrRange_push(). */
462 if (max != NULL) {
463 if ((asr = ASRange_new()) == NULL)
464 goto err;
465 }
466
467 if ((aor = ASIdOrRange_new()) == NULL)
468 goto err;
469 if (sk_ASIdOrRange_push(aors, aor) <= 0)
470 goto err;
471
472 if (max == NULL) {
473 aor->type = ASIdOrRange_id;
474 aor->u.id = min;
475 } else {
476 ASN1_INTEGER_free(asr->min);
477 asr->min = min;
478 ASN1_INTEGER_free(asr->max);
479 asr->max = max;
480
481 aor->type = ASIdOrRange_range;
482 aor->u.range = asr;
483 asr = NULL;
484 }
485
486 aor = NULL;
487
488 ret = 1;
489
490 err:
491 ASIdOrRange_free(aor);
492 ASRange_free(asr);
493
494 return ret;
495}
496
497/*
498 * Add an ID or range to an ASIdentifierChoice.
499 */
500int
501X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, ASN1_INTEGER *min,
502 ASN1_INTEGER *max)
503{
504 ASIdentifierChoice **choice;
505 ASIdentifierChoice *aic = NULL, *new_aic = NULL;
506 int ret = 0;
507
508 if (asid == NULL)
509 goto err;
510
511 switch (which) {
512 case V3_ASID_ASNUM:
513 choice = &asid->asnum;
514 break;
515 case V3_ASID_RDI:
516 choice = &asid->rdi;
517 break;
518 default:
519 goto err;
520 }
521
522 if ((aic = *choice) != NULL) {
523 if (aic->type != ASIdentifierChoice_asIdsOrRanges)
524 goto err;
525 } else {
526 if ((aic = new_aic = ASIdentifierChoice_new()) == NULL)
527 goto err;
528 aic->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
529 if (aic->u.asIdsOrRanges == NULL)
530 goto err;
531 aic->type = ASIdentifierChoice_asIdsOrRanges;
532 }
533
534 if (!ASIdOrRanges_add_id_or_range(aic->u.asIdsOrRanges, min, max))
535 goto err;
536
537 *choice = aic;
538 aic = new_aic = NULL;
539
540 ret = 1;
541
542 err:
543 ASIdentifierChoice_free(new_aic);
544
545 return ret;
546}
547LCRYPTO_ALIAS(X509v3_asid_add_id_or_range);
548
549/*
550 * Extract min and max values from an ASIdOrRange.
551 */
552static int
553extract_min_max(ASIdOrRange *aor, ASN1_INTEGER **min, ASN1_INTEGER **max)
554{
555 switch (aor->type) {
556 case ASIdOrRange_id:
557 *min = aor->u.id;
558 *max = aor->u.id;
559 return 1;
560 case ASIdOrRange_range:
561 *min = aor->u.range->min;
562 *max = aor->u.range->max;
563 return 1;
564 }
565 *min = NULL;
566 *max = NULL;
567
568 return 0;
569}
570
571/*
572 * Check whether an ASIdentifierChoice is in canonical form.
573 */
574static int
575ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
576{
577 ASIdOrRange *a, *b;
578 ASN1_INTEGER *a_min = NULL, *a_max = NULL, *b_min = NULL, *b_max = NULL;
579 ASN1_INTEGER *a_max_plus_one = NULL;
580 ASN1_INTEGER *orig;
581 BIGNUM *bn = NULL;
582 int i, ret = 0;
583
584 /*
585 * Empty element or inheritance is canonical.
586 */
587 if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
588 return 1;
589
590 /*
591 * If not a list, or if empty list, it's broken.
592 */
593 if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
594 sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
595 return 0;
596
597 /*
598 * It's a list, check it.
599 */
600 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
601 a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
602 b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
603
604 if (!extract_min_max(a, &a_min, &a_max) ||
605 !extract_min_max(b, &b_min, &b_max))
606 goto done;
607
608 /*
609 * Punt misordered list, overlapping start, or inverted range.
610 */
611 if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
612 ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
613 ASN1_INTEGER_cmp(b_min, b_max) > 0)
614 goto done;
615
616 /*
617 * Calculate a_max + 1 to check for adjacency.
618 */
619 if ((bn == NULL && (bn = BN_new()) == NULL) ||
620 ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
621 !BN_add_word(bn, 1)) {
622 X509V3error(ERR_R_MALLOC_FAILURE);
623 goto done;
624 }
625
626 if ((a_max_plus_one =
627 BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) {
628 a_max_plus_one = orig;
629 X509V3error(ERR_R_MALLOC_FAILURE);
630 goto done;
631 }
632
633 /*
634 * Punt if adjacent or overlapping.
635 */
636 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
637 goto done;
638 }
639
640 /*
641 * Check for inverted range.
642 */
643 i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
644 a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
645 if (a != NULL && a->type == ASIdOrRange_range) {
646 if (!extract_min_max(a, &a_min, &a_max) ||
647 ASN1_INTEGER_cmp(a_min, a_max) > 0)
648 goto done;
649 }
650
651 ret = 1;
652
653 done:
654 ASN1_INTEGER_free(a_max_plus_one);
655 BN_free(bn);
656 return ret;
657}
658
659/*
660 * Check whether an ASIdentifier extension is in canonical form.
661 */
662int
663X509v3_asid_is_canonical(ASIdentifiers *asid)
664{
665 return (asid == NULL ||
666 (ASIdentifierChoice_is_canonical(asid->asnum) &&
667 ASIdentifierChoice_is_canonical(asid->rdi)));
668}
669LCRYPTO_ALIAS(X509v3_asid_is_canonical);
670
671/*
672 * Whack an ASIdentifierChoice into canonical form.
673 */
674static int
675ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
676{
677 ASIdOrRange *a, *b;
678 ASN1_INTEGER *a_min = NULL, *a_max = NULL, *b_min = NULL, *b_max = NULL;
679 ASN1_INTEGER *a_max_plus_one = NULL;
680 ASN1_INTEGER *orig;
681 BIGNUM *bn = NULL;
682 int i, ret = 0;
683
684 /*
685 * Nothing to do for empty element or inheritance.
686 */
687 if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
688 return 1;
689
690 /*
691 * If not a list, or if empty list, it's broken.
692 */
693 if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
694 sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
695 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
696 return 0;
697 }
698
699 /*
700 * We have a non-empty list. Sort it.
701 */
702 sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
703
704 /*
705 * Now check for errors and suboptimal encoding, rejecting the
706 * former and fixing the latter.
707 */
708 for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
709 a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
710 b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
711
712 if (!extract_min_max(a, &a_min, &a_max) ||
713 !extract_min_max(b, &b_min, &b_max))
714 goto done;
715
716 /*
717 * Make sure we're properly sorted (paranoia).
718 */
719 if (ASN1_INTEGER_cmp(a_min, b_min) > 0)
720 goto done;
721
722 /*
723 * Punt inverted ranges.
724 */
725 if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
726 ASN1_INTEGER_cmp(b_min, b_max) > 0)
727 goto done;
728
729 /*
730 * Check for overlaps.
731 */
732 if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
733 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
734 goto done;
735 }
736
737 /*
738 * Calculate a_max + 1 to check for adjacency.
739 */
740 if ((bn == NULL && (bn = BN_new()) == NULL) ||
741 ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
742 !BN_add_word(bn, 1)) {
743 X509V3error(ERR_R_MALLOC_FAILURE);
744 goto done;
745 }
746
747 if ((a_max_plus_one =
748 BN_to_ASN1_INTEGER(bn, orig = a_max_plus_one)) == NULL) {
749 a_max_plus_one = orig;
750 X509V3error(ERR_R_MALLOC_FAILURE);
751 goto done;
752 }
753
754 /*
755 * If a and b are adjacent, merge them.
756 */
757 if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
758 ASRange *r;
759 switch (a->type) {
760 case ASIdOrRange_id:
761 if ((r = calloc(1, sizeof(*r))) == NULL) {
762 X509V3error(ERR_R_MALLOC_FAILURE);
763 goto done;
764 }
765 r->min = a_min;
766 r->max = b_max;
767 a->type = ASIdOrRange_range;
768 a->u.range = r;
769 break;
770 case ASIdOrRange_range:
771 ASN1_INTEGER_free(a->u.range->max);
772 a->u.range->max = b_max;
773 break;
774 }
775 switch (b->type) {
776 case ASIdOrRange_id:
777 b->u.id = NULL;
778 break;
779 case ASIdOrRange_range:
780 b->u.range->max = NULL;
781 break;
782 }
783 ASIdOrRange_free(b);
784 (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges,
785 i + 1);
786 i--;
787 continue;
788 }
789 }
790
791 /*
792 * Check for final inverted range.
793 */
794 i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
795 a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
796 if (a != NULL && a->type == ASIdOrRange_range) {
797 if (!extract_min_max(a, &a_min, &a_max) ||
798 ASN1_INTEGER_cmp(a_min, a_max) > 0)
799 goto done;
800 }
801
802 /* Paranoia */
803 if (!ASIdentifierChoice_is_canonical(choice))
804 goto done;
805
806 ret = 1;
807
808 done:
809 ASN1_INTEGER_free(a_max_plus_one);
810 BN_free(bn);
811 return ret;
812}
813
814/*
815 * Whack an ASIdentifier extension into canonical form.
816 */
817int
818X509v3_asid_canonize(ASIdentifiers *asid)
819{
820 if (asid == NULL)
821 return 1;
822
823 if (!ASIdentifierChoice_canonize(asid->asnum))
824 return 0;
825
826 return ASIdentifierChoice_canonize(asid->rdi);
827}
828LCRYPTO_ALIAS(X509v3_asid_canonize);
829
830/*
831 * v2i method for an ASIdentifier extension.
832 */
833static void *
834v2i_ASIdentifiers(const struct v3_ext_method *method, struct v3_ext_ctx *ctx,
835 STACK_OF(CONF_VALUE)*values)
836{
837 ASN1_INTEGER *min = NULL, *max = NULL;
838 ASIdentifiers *asid = NULL;
839 int i;
840
841 if ((asid = ASIdentifiers_new()) == NULL) {
842 X509V3error(ERR_R_MALLOC_FAILURE);
843 return NULL;
844 }
845
846 for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
847 CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
848 int i1 = 0, i2 = 0, i3 = 0, is_range = 0, which = 0;
849
850 /*
851 * Figure out whether this is an AS or an RDI.
852 */
853 if (!name_cmp(val->name, "AS")) {
854 which = V3_ASID_ASNUM;
855 } else if (!name_cmp(val->name, "RDI")) {
856 which = V3_ASID_RDI;
857 } else {
858 X509V3error(X509V3_R_EXTENSION_NAME_ERROR);
859 X509V3_conf_err(val);
860 goto err;
861 }
862
863 /*
864 * Handle inheritance.
865 */
866 if (strcmp(val->value, "inherit") == 0) {
867 if (X509v3_asid_add_inherit(asid, which))
868 continue;
869 X509V3error(X509V3_R_INVALID_INHERITANCE);
870 X509V3_conf_err(val);
871 goto err;
872 }
873
874 /*
875 * Number, range, or mistake, pick it apart and figure out which
876 */
877 i1 = strspn(val->value, "0123456789");
878 if (val->value[i1] == '\0') {
879 is_range = 0;
880 } else {
881 is_range = 1;
882 i2 = i1 + strspn(val->value + i1, " \t");
883 if (val->value[i2] != '-') {
884 X509V3error(X509V3_R_INVALID_ASNUMBER);
885 X509V3_conf_err(val);
886 goto err;
887 }
888 i2++;
889 i2 = i2 + strspn(val->value + i2, " \t");
890 i3 = i2 + strspn(val->value + i2, "0123456789");
891 if (val->value[i3] != '\0') {
892 X509V3error(X509V3_R_INVALID_ASRANGE);
893 X509V3_conf_err(val);
894 goto err;
895 }
896 }
897
898 /*
899 * Syntax is ok, read and add it.
900 */
901 if (!is_range) {
902 if (!X509V3_get_value_int(val, &min)) {
903 X509V3error(ERR_R_MALLOC_FAILURE);
904 goto err;
905 }
906 } else {
907 char *s = strdup(val->value);
908 if (s == NULL) {
909 X509V3error(ERR_R_MALLOC_FAILURE);
910 goto err;
911 }
912 s[i1] = '\0';
913 min = s2i_ASN1_INTEGER(NULL, s);
914 max = s2i_ASN1_INTEGER(NULL, s + i2);
915 free(s);
916 if (min == NULL || max == NULL) {
917 X509V3error(ERR_R_MALLOC_FAILURE);
918 goto err;
919 }
920 if (ASN1_INTEGER_cmp(min, max) > 0) {
921 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
922 goto err;
923 }
924 }
925 if (!X509v3_asid_add_id_or_range(asid, which, min, max)) {
926 X509V3error(ERR_R_MALLOC_FAILURE);
927 goto err;
928 }
929 min = max = NULL;
930 }
931
932 /*
933 * Canonize the result, then we're done.
934 */
935 if (!X509v3_asid_canonize(asid))
936 goto err;
937 return asid;
938
939 err:
940 ASIdentifiers_free(asid);
941 ASN1_INTEGER_free(min);
942 ASN1_INTEGER_free(max);
943 return NULL;
944}
945
946/*
947 * OpenSSL dispatch.
948 */
949static const X509V3_EXT_METHOD x509v3_ext_sbgp_autonomousSysNum = {
950 .ext_nid = NID_sbgp_autonomousSysNum,
951 .ext_flags = 0,
952 .it = &ASIdentifiers_it,
953 .ext_new = NULL,
954 .ext_free = NULL,
955 .d2i = NULL,
956 .i2d = NULL,
957 .i2s = NULL,
958 .s2i = NULL,
959 .i2v = NULL,
960 .v2i = v2i_ASIdentifiers,
961 .i2r = i2r_ASIdentifiers,
962 .r2i = NULL,
963 .usr_data = NULL,
964};
965
966const X509V3_EXT_METHOD *
967x509v3_ext_method_sbgp_autonomousSysNum(void)
968{
969 return &x509v3_ext_sbgp_autonomousSysNum;
970}
971
972/*
973 * Figure out whether extension uses inheritance.
974 */
975int
976X509v3_asid_inherits(ASIdentifiers *asid)
977{
978 if (asid == NULL)
979 return 0;
980
981 if (asid->asnum != NULL) {
982 if (asid->asnum->type == ASIdentifierChoice_inherit)
983 return 1;
984 }
985
986 if (asid->rdi != NULL) {
987 if (asid->rdi->type == ASIdentifierChoice_inherit)
988 return 1;
989 }
990
991 return 0;
992}
993LCRYPTO_ALIAS(X509v3_asid_inherits);
994
995/*
996 * Figure out whether parent contains child.
997 */
998static int
999asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
1000{
1001 ASN1_INTEGER *p_min = NULL, *p_max = NULL, *c_min = NULL, *c_max = NULL;
1002 int p, c;
1003
1004 if (child == NULL || parent == child)
1005 return 1;
1006
1007 if (parent == NULL)
1008 return 0;
1009
1010 p = 0;
1011 for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
1012 if (!extract_min_max(sk_ASIdOrRange_value(child, c), &c_min,
1013 &c_max))
1014 return 0;
1015 for (;; p++) {
1016 if (p >= sk_ASIdOrRange_num(parent))
1017 return 0;
1018 if (!extract_min_max(sk_ASIdOrRange_value(parent, p),
1019 &p_min, &p_max))
1020 return 0;
1021 if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
1022 continue;
1023 if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
1024 return 0;
1025 break;
1026 }
1027 }
1028
1029 return 1;
1030}
1031
1032/*
1033 * Test whether child is a subset of parent.
1034 */
1035int
1036X509v3_asid_subset(ASIdentifiers *child, ASIdentifiers *parent)
1037{
1038 if (child == NULL || child == parent)
1039 return 1;
1040
1041 if (parent == NULL)
1042 return 0;
1043
1044 if (X509v3_asid_inherits(child) || X509v3_asid_inherits(parent))
1045 return 0;
1046
1047 if (child->asnum != NULL) {
1048 if (parent->asnum == NULL)
1049 return 0;
1050
1051 if (!asid_contains(parent->asnum->u.asIdsOrRanges,
1052 child->asnum->u.asIdsOrRanges))
1053 return 0;
1054 }
1055
1056 if (child->rdi != NULL) {
1057 if (parent->rdi == NULL)
1058 return 0;
1059
1060 if (!asid_contains(parent->rdi->u.asIdsOrRanges,
1061 child->rdi->u.asIdsOrRanges))
1062 return 0;
1063 }
1064
1065 return 1;
1066}
1067LCRYPTO_ALIAS(X509v3_asid_subset);
1068
1069/*
1070 * Validation error handling via callback.
1071 */
1072#define validation_err(_err_) \
1073 do { \
1074 if (ctx != NULL) { \
1075 ctx->error = _err_; \
1076 ctx->error_depth = i; \
1077 ctx->current_cert = x; \
1078 ret = ctx->verify_cb(0, ctx); \
1079 } else { \
1080 ret = 0; \
1081 } \
1082 if (!ret) \
1083 goto done; \
1084 } while (0)
1085
1086/*
1087 * Core code for RFC 3779 3.3 path validation.
1088 */
1089static int
1090asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain,
1091 ASIdentifiers *ext)
1092{
1093 ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
1094 int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
1095 X509 *x;
1096
1097 /* We need a non-empty chain to test against. */
1098 if (sk_X509_num(chain) <= 0)
1099 goto err;
1100 /* We need either a store ctx or an extension to work with. */
1101 if (ctx == NULL && ext == NULL)
1102 goto err;
1103 /* If there is a store ctx, it needs a verify_cb. */
1104 if (ctx != NULL && ctx->verify_cb == NULL)
1105 goto err;
1106
1107 /*
1108 * Figure out where to start. If we don't have an extension to check,
1109 * (either extracted from the leaf or passed by the caller), we're done.
1110 * Otherwise, check canonical form and set up for walking up the chain.
1111 */
1112 if (ext != NULL) {
1113 i = -1;
1114 x = NULL;
1115 if (!X509v3_asid_is_canonical(ext))
1116 validation_err(X509_V_ERR_INVALID_EXTENSION);
1117 } else {
1118 i = 0;
1119 x = sk_X509_value(chain, i);
1120 if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0)
1121 goto done;
1122 if ((ext = x->rfc3779_asid) == NULL)
1123 goto done;
1124 }
1125 if (ext->asnum != NULL) {
1126 switch (ext->asnum->type) {
1127 case ASIdentifierChoice_inherit:
1128 inherit_as = 1;
1129 break;
1130 case ASIdentifierChoice_asIdsOrRanges:
1131 child_as = ext->asnum->u.asIdsOrRanges;
1132 break;
1133 }
1134 }
1135 if (ext->rdi != NULL) {
1136 switch (ext->rdi->type) {
1137 case ASIdentifierChoice_inherit:
1138 inherit_rdi = 1;
1139 break;
1140 case ASIdentifierChoice_asIdsOrRanges:
1141 child_rdi = ext->rdi->u.asIdsOrRanges;
1142 break;
1143 }
1144 }
1145
1146 /*
1147 * Now walk up the chain. Extensions must be in canonical form, no
1148 * cert may list resources that its parent doesn't list.
1149 */
1150 for (i++; i < sk_X509_num(chain); i++) {
1151 x = sk_X509_value(chain, i);
1152
1153 if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0)
1154 validation_err(X509_V_ERR_INVALID_EXTENSION);
1155 if (x->rfc3779_asid == NULL) {
1156 if (child_as != NULL || child_rdi != NULL)
1157 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1158 continue;
1159 }
1160 if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
1161 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1162 child_as = NULL;
1163 inherit_as = 0;
1164 }
1165 if (x->rfc3779_asid->asnum != NULL &&
1166 x->rfc3779_asid->asnum->type ==
1167 ASIdentifierChoice_asIdsOrRanges) {
1168 if (inherit_as ||
1169 asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges,
1170 child_as)) {
1171 child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
1172 inherit_as = 0;
1173 } else {
1174 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1175 }
1176 }
1177 if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
1178 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1179 child_rdi = NULL;
1180 inherit_rdi = 0;
1181 }
1182 if (x->rfc3779_asid->rdi != NULL &&
1183 x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
1184 if (inherit_rdi ||
1185 asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges,
1186 child_rdi)) {
1187 child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
1188 inherit_rdi = 0;
1189 } else {
1190 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1191 }
1192 }
1193 }
1194
1195 /*
1196 * Trust anchor can't inherit.
1197 */
1198
1199 if (x == NULL)
1200 goto err;
1201
1202 if (x->rfc3779_asid != NULL) {
1203 if (x->rfc3779_asid->asnum != NULL &&
1204 x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
1205 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1206 if (x->rfc3779_asid->rdi != NULL &&
1207 x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
1208 validation_err(X509_V_ERR_UNNESTED_RESOURCE);
1209 }
1210
1211 done:
1212 return ret;
1213
1214 err:
1215 if (ctx != NULL)
1216 ctx->error = X509_V_ERR_UNSPECIFIED;
1217
1218 return 0;
1219}
1220
1221#undef validation_err
1222
1223/*
1224 * RFC 3779 3.3 path validation -- called from X509_verify_cert().
1225 */
1226int
1227X509v3_asid_validate_path(X509_STORE_CTX *ctx)
1228{
1229 if (sk_X509_num(ctx->chain) <= 0 || ctx->verify_cb == NULL) {
1230 ctx->error = X509_V_ERR_UNSPECIFIED;
1231 return 0;
1232 }
1233 return asid_validate_path_internal(ctx, ctx->chain, NULL);
1234}
1235LCRYPTO_ALIAS(X509v3_asid_validate_path);
1236
1237/*
1238 * RFC 3779 3.3 path validation of an extension.
1239 * Test whether chain covers extension.
1240 */
1241int
1242X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext,
1243 int allow_inheritance)
1244{
1245 if (ext == NULL)
1246 return 1;
1247 if (sk_X509_num(chain) <= 0)
1248 return 0;
1249 if (!allow_inheritance && X509v3_asid_inherits(ext))
1250 return 0;
1251 return asid_validate_path_internal(NULL, chain, ext);
1252}
1253LCRYPTO_ALIAS(X509v3_asid_validate_resource_set);
1254
1255#endif /* OPENSSL_NO_RFC3779 */
diff --git a/src/lib/libcrypto/x509/x509_att.c b/src/lib/libcrypto/x509/x509_att.c
deleted file mode 100644
index 4931cbbc17..0000000000
--- a/src/lib/libcrypto/x509/x509_att.c
+++ /dev/null
@@ -1,377 +0,0 @@
1/* $OpenBSD: x509_att.c,v 1.25 2024/08/31 10:46:40 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/err.h>
63#include <openssl/evp.h>
64#include <openssl/objects.h>
65#include <openssl/stack.h>
66#include <openssl/x509.h>
67#include <openssl/x509v3.h>
68
69#include "x509_local.h"
70
71int
72X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, int lastpos)
73{
74 ASN1_OBJECT *obj;
75
76 obj = OBJ_nid2obj(nid);
77 if (obj == NULL)
78 return (-2);
79 return (X509at_get_attr_by_OBJ(x, obj, lastpos));
80}
81
82int
83X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
84 const ASN1_OBJECT *obj, int lastpos)
85{
86 int n;
87 X509_ATTRIBUTE *ex;
88
89 if (sk == NULL)
90 return (-1);
91 lastpos++;
92 if (lastpos < 0)
93 lastpos = 0;
94 n = sk_X509_ATTRIBUTE_num(sk);
95 for (; lastpos < n; lastpos++) {
96 ex = sk_X509_ATTRIBUTE_value(sk, lastpos);
97 if (OBJ_cmp(ex->object, obj) == 0)
98 return (lastpos);
99 }
100 return (-1);
101}
102
103STACK_OF(X509_ATTRIBUTE) *
104X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, X509_ATTRIBUTE *attr)
105{
106 X509_ATTRIBUTE *new_attr = NULL;
107 STACK_OF(X509_ATTRIBUTE) *sk = NULL;
108
109 if (x == NULL) {
110 X509error(ERR_R_PASSED_NULL_PARAMETER);
111 return (NULL);
112 }
113
114 if (*x == NULL) {
115 if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
116 goto err;
117 } else
118 sk = *x;
119
120 if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL)
121 goto err2;
122 if (!sk_X509_ATTRIBUTE_push(sk, new_attr))
123 goto err;
124 if (*x == NULL)
125 *x = sk;
126 return (sk);
127
128err:
129 X509error(ERR_R_MALLOC_FAILURE);
130err2:
131 if (new_attr != NULL)
132 X509_ATTRIBUTE_free(new_attr);
133 if (sk != NULL && sk != *x)
134 sk_X509_ATTRIBUTE_free(sk);
135 return (NULL);
136}
137
138STACK_OF(X509_ATTRIBUTE) *
139X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, const ASN1_OBJECT *obj,
140 int type, const unsigned char *bytes, int len)
141{
142 X509_ATTRIBUTE *attr;
143 STACK_OF(X509_ATTRIBUTE) *ret;
144
145 attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
146 if (!attr)
147 return 0;
148 ret = X509at_add1_attr(x, attr);
149 X509_ATTRIBUTE_free(attr);
150 return ret;
151}
152
153STACK_OF(X509_ATTRIBUTE) *
154X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, int nid, int type,
155 const unsigned char *bytes, int len)
156{
157 X509_ATTRIBUTE *attr;
158 STACK_OF(X509_ATTRIBUTE) *ret;
159
160 attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
161 if (!attr)
162 return 0;
163 ret = X509at_add1_attr(x, attr);
164 X509_ATTRIBUTE_free(attr);
165 return ret;
166}
167
168STACK_OF(X509_ATTRIBUTE) *
169X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, const char *attrname,
170 int type, const unsigned char *bytes, int len)
171{
172 X509_ATTRIBUTE *attr;
173 STACK_OF(X509_ATTRIBUTE) *ret;
174
175 attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
176 if (!attr)
177 return 0;
178 ret = X509at_add1_attr(x, attr);
179 X509_ATTRIBUTE_free(attr);
180 return ret;
181}
182
183void *
184X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, const ASN1_OBJECT *obj,
185 int lastpos, int type)
186{
187 int i;
188 X509_ATTRIBUTE *at;
189
190 i = X509at_get_attr_by_OBJ(x, obj, lastpos);
191 if (i == -1)
192 return NULL;
193 if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
194 return NULL;
195 at = sk_X509_ATTRIBUTE_value(x, i);
196 if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
197 return NULL;
198 return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
199}
200
201X509_ATTRIBUTE *
202X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int atrtype,
203 const void *data, int len)
204{
205 ASN1_OBJECT *obj;
206 X509_ATTRIBUTE *ret;
207
208 obj = OBJ_nid2obj(nid);
209 if (obj == NULL) {
210 X509error(X509_R_UNKNOWN_NID);
211 return (NULL);
212 }
213 ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
214 if (ret == NULL)
215 ASN1_OBJECT_free(obj);
216 return (ret);
217}
218LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_NID);
219
220X509_ATTRIBUTE *
221X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, const ASN1_OBJECT *obj,
222 int atrtype, const void *data, int len)
223{
224 X509_ATTRIBUTE *ret;
225
226 if ((attr == NULL) || (*attr == NULL)) {
227 if ((ret = X509_ATTRIBUTE_new()) == NULL) {
228 X509error(ERR_R_MALLOC_FAILURE);
229 return (NULL);
230 }
231 } else
232 ret= *attr;
233
234 if (!X509_ATTRIBUTE_set1_object(ret, obj))
235 goto err;
236 if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
237 goto err;
238
239 if ((attr != NULL) && (*attr == NULL))
240 *attr = ret;
241 return (ret);
242
243err:
244 if ((attr == NULL) || (ret != *attr))
245 X509_ATTRIBUTE_free(ret);
246 return (NULL);
247}
248LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_OBJ);
249
250X509_ATTRIBUTE *
251X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, const char *atrname,
252 int type, const unsigned char *bytes, int len)
253{
254 ASN1_OBJECT *obj;
255 X509_ATTRIBUTE *nattr;
256
257 obj = OBJ_txt2obj(atrname, 0);
258 if (obj == NULL) {
259 X509error(X509_R_INVALID_FIELD_NAME);
260 ERR_asprintf_error_data("name=%s", atrname);
261 return (NULL);
262 }
263 nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
264 ASN1_OBJECT_free(obj);
265 return nattr;
266}
267LCRYPTO_ALIAS(X509_ATTRIBUTE_create_by_txt);
268
269int
270X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
271{
272 if ((attr == NULL) || (obj == NULL))
273 return (0);
274 ASN1_OBJECT_free(attr->object);
275 attr->object = OBJ_dup(obj);
276 return attr->object != NULL;
277}
278LCRYPTO_ALIAS(X509_ATTRIBUTE_set1_object);
279
280int
281X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data,
282 int len)
283{
284 ASN1_TYPE *ttmp = NULL;
285 ASN1_STRING *stmp = NULL;
286 int atype = 0;
287
288 if (!attr)
289 return 0;
290 if (attrtype & MBSTRING_FLAG) {
291 stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
292 OBJ_obj2nid(attr->object));
293 if (!stmp) {
294 X509error(ERR_R_ASN1_LIB);
295 return 0;
296 }
297 atype = stmp->type;
298 } else if (len != -1){
299 if (!(stmp = ASN1_STRING_type_new(attrtype)))
300 goto err;
301 if (!ASN1_STRING_set(stmp, data, len))
302 goto err;
303 atype = attrtype;
304 }
305 /*
306 * This is a bit naughty because the attribute should really have
307 * at least one value but some types use and zero length SET and
308 * require this.
309 */
310 if (attrtype == 0) {
311 ASN1_STRING_free(stmp);
312 return 1;
313 }
314
315 if (!(ttmp = ASN1_TYPE_new()))
316 goto err;
317 if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
318 if (!ASN1_TYPE_set1(ttmp, attrtype, data))
319 goto err;
320 } else
321 ASN1_TYPE_set(ttmp, atype, stmp);
322 if (!sk_ASN1_TYPE_push(attr->set, ttmp))
323 goto err;
324 return 1;
325
326err:
327 ASN1_TYPE_free(ttmp);
328 ASN1_STRING_free(stmp);
329 X509error(ERR_R_MALLOC_FAILURE);
330 return 0;
331}
332LCRYPTO_ALIAS(X509_ATTRIBUTE_set1_data);
333
334int
335X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr)
336{
337 if (attr == NULL)
338 return 0;
339
340 return sk_ASN1_TYPE_num(attr->set);
341}
342LCRYPTO_ALIAS(X509_ATTRIBUTE_count);
343
344ASN1_OBJECT *
345X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
346{
347 if (attr == NULL)
348 return (NULL);
349 return (attr->object);
350}
351LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_object);
352
353void *
354X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, void *data)
355{
356 ASN1_TYPE *ttmp;
357
358 ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
359 if (!ttmp)
360 return NULL;
361 if (atrtype != ASN1_TYPE_get(ttmp)){
362 X509error(X509_R_WRONG_TYPE);
363 return NULL;
364 }
365 return ttmp->value.ptr;
366}
367LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_data);
368
369ASN1_TYPE *
370X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
371{
372 if (attr == NULL)
373 return (NULL);
374
375 return sk_ASN1_TYPE_value(attr->set, idx);
376}
377LCRYPTO_ALIAS(X509_ATTRIBUTE_get0_type);
diff --git a/src/lib/libcrypto/x509/x509_bcons.c b/src/lib/libcrypto/x509/x509_bcons.c
deleted file mode 100644
index 99cb5afe9a..0000000000
--- a/src/lib/libcrypto/x509/x509_bcons.c
+++ /dev/null
@@ -1,212 +0,0 @@
1/* $OpenBSD: x509_bcons.c,v 1.6 2024/08/31 10:03:03 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
64#include <openssl/conf.h>
65#include <openssl/err.h>
66#include <openssl/x509v3.h>
67
68#include "x509_local.h"
69
70static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
71 BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist);
72static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
73 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
74
75static const X509V3_EXT_METHOD x509v3_ext_basic_constraints = {
76 .ext_nid = NID_basic_constraints,
77 .ext_flags = 0,
78 .it = &BASIC_CONSTRAINTS_it,
79 .ext_new = NULL,
80 .ext_free = NULL,
81 .d2i = NULL,
82 .i2d = NULL,
83 .i2s = NULL,
84 .s2i = NULL,
85 .i2v = (X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS,
86 .v2i = (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
87 .i2r = NULL,
88 .r2i = NULL,
89 .usr_data = NULL,
90};
91
92const X509V3_EXT_METHOD *
93x509v3_ext_method_basic_constraints(void)
94{
95 return &x509v3_ext_basic_constraints;
96}
97
98static const ASN1_TEMPLATE BASIC_CONSTRAINTS_seq_tt[] = {
99 {
100 .flags = ASN1_TFLG_OPTIONAL,
101 .tag = 0,
102 .offset = offsetof(BASIC_CONSTRAINTS, ca),
103 .field_name = "ca",
104 .item = &ASN1_FBOOLEAN_it,
105 },
106 {
107 .flags = ASN1_TFLG_OPTIONAL,
108 .tag = 0,
109 .offset = offsetof(BASIC_CONSTRAINTS, pathlen),
110 .field_name = "pathlen",
111 .item = &ASN1_INTEGER_it,
112 },
113};
114
115const ASN1_ITEM BASIC_CONSTRAINTS_it = {
116 .itype = ASN1_ITYPE_SEQUENCE,
117 .utype = V_ASN1_SEQUENCE,
118 .templates = BASIC_CONSTRAINTS_seq_tt,
119 .tcount = sizeof(BASIC_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE),
120 .funcs = NULL,
121 .size = sizeof(BASIC_CONSTRAINTS),
122 .sname = "BASIC_CONSTRAINTS",
123};
124LCRYPTO_ALIAS(BASIC_CONSTRAINTS_it);
125
126
127BASIC_CONSTRAINTS *
128d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, const unsigned char **in, long len)
129{
130 return (BASIC_CONSTRAINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
131 &BASIC_CONSTRAINTS_it);
132}
133LCRYPTO_ALIAS(d2i_BASIC_CONSTRAINTS);
134
135int
136i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out)
137{
138 return ASN1_item_i2d((ASN1_VALUE *)a, out, &BASIC_CONSTRAINTS_it);
139}
140LCRYPTO_ALIAS(i2d_BASIC_CONSTRAINTS);
141
142BASIC_CONSTRAINTS *
143BASIC_CONSTRAINTS_new(void)
144{
145 return (BASIC_CONSTRAINTS *)ASN1_item_new(&BASIC_CONSTRAINTS_it);
146}
147LCRYPTO_ALIAS(BASIC_CONSTRAINTS_new);
148
149void
150BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a)
151{
152 ASN1_item_free((ASN1_VALUE *)a, &BASIC_CONSTRAINTS_it);
153}
154LCRYPTO_ALIAS(BASIC_CONSTRAINTS_free);
155
156
157static STACK_OF(CONF_VALUE) *
158i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons,
159 STACK_OF(CONF_VALUE) *extlist)
160{
161 STACK_OF(CONF_VALUE) *free_extlist = NULL;
162
163 if (extlist == NULL) {
164 if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
165 return NULL;
166 }
167
168 if (!X509V3_add_value_bool("CA", bcons->ca, &extlist))
169 goto err;
170 if (!X509V3_add_value_int("pathlen", bcons->pathlen, &extlist))
171 goto err;
172
173 return extlist;
174
175 err:
176 sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
177
178 return NULL;
179}
180
181static BASIC_CONSTRAINTS *
182v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
183 STACK_OF(CONF_VALUE) *values)
184{
185 BASIC_CONSTRAINTS *bcons = NULL;
186 CONF_VALUE *val;
187 int i;
188
189 if (!(bcons = BASIC_CONSTRAINTS_new())) {
190 X509V3error(ERR_R_MALLOC_FAILURE);
191 return NULL;
192 }
193 for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
194 val = sk_CONF_VALUE_value(values, i);
195 if (!strcmp(val->name, "CA")) {
196 if (!X509V3_get_value_bool(val, &bcons->ca))
197 goto err;
198 } else if (!strcmp(val->name, "pathlen")) {
199 if (!X509V3_get_value_int(val, &bcons->pathlen))
200 goto err;
201 } else {
202 X509V3error(X509V3_R_INVALID_NAME);
203 X509V3_conf_err(val);
204 goto err;
205 }
206 }
207 return bcons;
208
209err:
210 BASIC_CONSTRAINTS_free(bcons);
211 return NULL;
212}
diff --git a/src/lib/libcrypto/x509/x509_bitst.c b/src/lib/libcrypto/x509/x509_bitst.c
deleted file mode 100644
index 2bc4f9911a..0000000000
--- a/src/lib/libcrypto/x509/x509_bitst.c
+++ /dev/null
@@ -1,240 +0,0 @@
1/* $OpenBSD: x509_bitst.c,v 1.8 2024/08/31 10:23:13 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/conf.h>
63#include <openssl/err.h>
64#include <openssl/x509v3.h>
65
66#include "x509_local.h"
67
68static const BIT_STRING_BITNAME ns_cert_type_table[] = {
69 {0, "SSL Client", "client"},
70 {1, "SSL Server", "server"},
71 {2, "S/MIME", "email"},
72 {3, "Object Signing", "objsign"},
73 {4, "Unused", "reserved"},
74 {5, "SSL CA", "sslCA"},
75 {6, "S/MIME CA", "emailCA"},
76 {7, "Object Signing CA", "objCA"},
77 {-1, NULL, NULL}
78};
79
80static const BIT_STRING_BITNAME key_usage_type_table[] = {
81 {0, "Digital Signature", "digitalSignature"},
82 {1, "Non Repudiation", "nonRepudiation"},
83 {2, "Key Encipherment", "keyEncipherment"},
84 {3, "Data Encipherment", "dataEncipherment"},
85 {4, "Key Agreement", "keyAgreement"},
86 {5, "Certificate Sign", "keyCertSign"},
87 {6, "CRL Sign", "cRLSign"},
88 {7, "Encipher Only", "encipherOnly"},
89 {8, "Decipher Only", "decipherOnly"},
90 {-1, NULL, NULL}
91};
92
93static const BIT_STRING_BITNAME crl_reasons[] = {
94 {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
95 {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
96 {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
97 {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
98 {CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
99 {CRL_REASON_CESSATION_OF_OPERATION, "Cessation Of Operation", "cessationOfOperation"},
100 {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
101 {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
102 {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
103 {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
104 {-1, NULL, NULL}
105};
106
107static const X509V3_EXT_METHOD x509v3_ext_netscape_cert_type = {
108 .ext_nid = NID_netscape_cert_type,
109 .ext_flags = 0,
110 .it = &ASN1_BIT_STRING_it,
111 .ext_new = NULL,
112 .ext_free = NULL,
113 .d2i = NULL,
114 .i2d = NULL,
115 .i2s = NULL,
116 .s2i = NULL,
117 .i2v = (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING,
118 .v2i = (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING,
119 .i2r = NULL,
120 .r2i = NULL,
121 .usr_data = ns_cert_type_table,
122};
123
124const X509V3_EXT_METHOD *
125x509v3_ext_method_netscape_cert_type(void)
126{
127 return &x509v3_ext_netscape_cert_type;
128}
129
130static const X509V3_EXT_METHOD x509v3_ext_key_usage = {
131 .ext_nid = NID_key_usage,
132 .ext_flags = 0,
133 .it = &ASN1_BIT_STRING_it,
134 .ext_new = NULL,
135 .ext_free = NULL,
136 .d2i = NULL,
137 .i2d = NULL,
138 .i2s = NULL,
139 .s2i = NULL,
140 .i2v = (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING,
141 .v2i = (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING,
142 .i2r = NULL,
143 .r2i = NULL,
144 .usr_data = key_usage_type_table,
145};
146
147const X509V3_EXT_METHOD *
148x509v3_ext_method_key_usage(void)
149{
150 return &x509v3_ext_key_usage;
151}
152
153static const X509V3_EXT_METHOD x509v3_ext_crl_reason = {
154 .ext_nid = NID_crl_reason,
155 .ext_flags = 0,
156 .it = &ASN1_ENUMERATED_it,
157 .ext_new = NULL,
158 .ext_free = NULL,
159 .d2i = NULL,
160 .i2d = NULL,
161 .i2s = (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
162 .s2i = NULL,
163 .i2v = NULL,
164 .v2i = NULL,
165 .i2r = NULL,
166 .r2i = NULL,
167 .usr_data = crl_reasons,
168};
169
170const X509V3_EXT_METHOD *
171x509v3_ext_method_crl_reason(void)
172{
173 return &x509v3_ext_crl_reason;
174}
175
176STACK_OF(CONF_VALUE) *
177i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, ASN1_BIT_STRING *bits,
178 STACK_OF(CONF_VALUE) *ret)
179{
180 const BIT_STRING_BITNAME *bnam;
181 STACK_OF(CONF_VALUE) *free_ret = NULL;
182
183 if (ret == NULL) {
184 if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
185 return NULL;
186 }
187
188 for (bnam = method->usr_data; bnam->lname != NULL; bnam++) {
189 if (!ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
190 continue;
191 if (!X509V3_add_value(bnam->lname, NULL, &ret))
192 goto err;
193 }
194
195 return ret;
196
197 err:
198 sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
199
200 return NULL;
201}
202LCRYPTO_ALIAS(i2v_ASN1_BIT_STRING);
203
204ASN1_BIT_STRING *
205v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
206 STACK_OF(CONF_VALUE) *nval)
207{
208 CONF_VALUE *val;
209 ASN1_BIT_STRING *bs;
210 int i;
211 const BIT_STRING_BITNAME *bnam;
212
213 if (!(bs = ASN1_BIT_STRING_new())) {
214 X509V3error(ERR_R_MALLOC_FAILURE);
215 return NULL;
216 }
217 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
218 val = sk_CONF_VALUE_value(nval, i);
219 for (bnam = method->usr_data; bnam->lname; bnam++) {
220 if (!strcmp(bnam->sname, val->name) ||
221 !strcmp(bnam->lname, val->name) ) {
222 if (!ASN1_BIT_STRING_set_bit(bs,
223 bnam->bitnum, 1)) {
224 X509V3error(ERR_R_MALLOC_FAILURE);
225 ASN1_BIT_STRING_free(bs);
226 return NULL;
227 }
228 break;
229 }
230 }
231 if (!bnam->lname) {
232 X509V3error(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
233 X509V3_conf_err(val);
234 ASN1_BIT_STRING_free(bs);
235 return NULL;
236 }
237 }
238 return bs;
239}
240LCRYPTO_ALIAS(v2i_ASN1_BIT_STRING);
diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c
deleted file mode 100644
index 2c1e427093..0000000000
--- a/src/lib/libcrypto/x509/x509_cmp.c
+++ /dev/null
@@ -1,429 +0,0 @@
1/* $OpenBSD: x509_cmp.c,v 1.44 2024/03/25 03:41:16 joshua Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <ctype.h>
60#include <stdio.h>
61#include <string.h>
62
63#include <openssl/opensslconf.h>
64
65#include <openssl/asn1.h>
66#include <openssl/err.h>
67#include <openssl/objects.h>
68#include <openssl/x509.h>
69#include <openssl/x509v3.h>
70
71#include "evp_local.h"
72#include "x509_local.h"
73
74int
75X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
76{
77 int i;
78 X509_CINF *ai, *bi;
79
80 ai = a->cert_info;
81 bi = b->cert_info;
82 i = ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
83 if (i)
84 return (i);
85 return (X509_NAME_cmp(ai->issuer, bi->issuer));
86}
87LCRYPTO_ALIAS(X509_issuer_and_serial_cmp);
88
89#ifndef OPENSSL_NO_MD5
90unsigned long
91X509_issuer_and_serial_hash(X509 *a)
92{
93 unsigned long ret = 0;
94 EVP_MD_CTX *md_ctx;
95 unsigned char md[16];
96 char *f = NULL;
97
98 if ((md_ctx = EVP_MD_CTX_new()) == NULL)
99 goto err;
100
101 if ((f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0)) == NULL)
102 goto err;
103 if (!EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL))
104 goto err;
105 if (!EVP_DigestUpdate(md_ctx, (unsigned char *)f, strlen(f)))
106 goto err;
107 if (!EVP_DigestUpdate(md_ctx,
108 (unsigned char *)a->cert_info->serialNumber->data,
109 (unsigned long)a->cert_info->serialNumber->length))
110 goto err;
111 if (!EVP_DigestFinal_ex(md_ctx, &(md[0]), NULL))
112 goto err;
113
114 ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
115 ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) &
116 0xffffffffL;
117
118err:
119 EVP_MD_CTX_free(md_ctx);
120 free(f);
121
122 return ret;
123}
124LCRYPTO_ALIAS(X509_issuer_and_serial_hash);
125#endif
126
127int
128X509_issuer_name_cmp(const X509 *a, const X509 *b)
129{
130 return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
131}
132LCRYPTO_ALIAS(X509_issuer_name_cmp);
133
134int
135X509_subject_name_cmp(const X509 *a, const X509 *b)
136{
137 return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
138}
139LCRYPTO_ALIAS(X509_subject_name_cmp);
140
141int
142X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
143{
144 return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer));
145}
146LCRYPTO_ALIAS(X509_CRL_cmp);
147
148#ifndef OPENSSL_NO_SHA
149int
150X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
151{
152 return memcmp(a->hash, b->hash, X509_CRL_HASH_LEN);
153}
154LCRYPTO_ALIAS(X509_CRL_match);
155#endif
156
157X509_NAME *
158X509_get_issuer_name(const X509 *a)
159{
160 return (a->cert_info->issuer);
161}
162LCRYPTO_ALIAS(X509_get_issuer_name);
163
164unsigned long
165X509_issuer_name_hash(X509 *x)
166{
167 return (X509_NAME_hash(x->cert_info->issuer));
168}
169LCRYPTO_ALIAS(X509_issuer_name_hash);
170
171#ifndef OPENSSL_NO_MD5
172unsigned long
173X509_issuer_name_hash_old(X509 *x)
174{
175 return (X509_NAME_hash_old(x->cert_info->issuer));
176}
177LCRYPTO_ALIAS(X509_issuer_name_hash_old);
178#endif
179
180X509_NAME *
181X509_get_subject_name(const X509 *a)
182{
183 return (a->cert_info->subject);
184}
185LCRYPTO_ALIAS(X509_get_subject_name);
186
187ASN1_INTEGER *
188X509_get_serialNumber(X509 *a)
189{
190 return (a->cert_info->serialNumber);
191}
192LCRYPTO_ALIAS(X509_get_serialNumber);
193
194const ASN1_INTEGER *
195X509_get0_serialNumber(const X509 *a)
196{
197 return (a->cert_info->serialNumber);
198}
199LCRYPTO_ALIAS(X509_get0_serialNumber);
200
201unsigned long
202X509_subject_name_hash(X509 *x)
203{
204 return (X509_NAME_hash(x->cert_info->subject));
205}
206LCRYPTO_ALIAS(X509_subject_name_hash);
207
208#ifndef OPENSSL_NO_MD5
209unsigned long
210X509_subject_name_hash_old(X509 *x)
211{
212 return (X509_NAME_hash_old(x->cert_info->subject));
213}
214LCRYPTO_ALIAS(X509_subject_name_hash_old);
215#endif
216
217#ifndef OPENSSL_NO_SHA
218/* Compare two certificates: they must be identical for
219 * this to work. NB: Although "cmp" operations are generally
220 * prototyped to take "const" arguments (eg. for use in
221 * STACKs), the way X509 handling is - these operations may
222 * involve ensuring the hashes are up-to-date and ensuring
223 * certain cert information is cached. So this is the point
224 * where the "depth-first" constification tree has to halt
225 * with an evil cast.
226 */
227int
228X509_cmp(const X509 *a, const X509 *b)
229{
230 /* ensure hash is valid */
231 X509_check_purpose((X509 *)a, -1, 0);
232 X509_check_purpose((X509 *)b, -1, 0);
233
234 return memcmp(a->hash, b->hash, X509_CERT_HASH_LEN);
235}
236LCRYPTO_ALIAS(X509_cmp);
237#endif
238
239int
240X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
241{
242 int ret;
243
244 /* Ensure canonical encoding is present and up to date */
245 if (!a->canon_enc || a->modified) {
246 ret = i2d_X509_NAME((X509_NAME *)a, NULL);
247 if (ret < 0)
248 return -2;
249 }
250 if (!b->canon_enc || b->modified) {
251 ret = i2d_X509_NAME((X509_NAME *)b, NULL);
252 if (ret < 0)
253 return -2;
254 }
255 ret = a->canon_enclen - b->canon_enclen;
256 if (ret)
257 return ret;
258 return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
259}
260LCRYPTO_ALIAS(X509_NAME_cmp);
261
262unsigned long
263X509_NAME_hash(X509_NAME *x)
264{
265 unsigned long ret = 0;
266 unsigned char md[SHA_DIGEST_LENGTH];
267
268 /* Make sure X509_NAME structure contains valid cached encoding */
269 i2d_X509_NAME(x, NULL);
270 if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
271 NULL))
272 return 0;
273
274 ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
275 ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) &
276 0xffffffffL;
277 return (ret);
278}
279LCRYPTO_ALIAS(X509_NAME_hash);
280
281
282#ifndef OPENSSL_NO_MD5
283/* I now DER encode the name and hash it. Since I cache the DER encoding,
284 * this is reasonably efficient. */
285
286unsigned long
287X509_NAME_hash_old(X509_NAME *x)
288{
289 EVP_MD_CTX *md_ctx;
290 unsigned long ret = 0;
291 unsigned char md[16];
292
293 if ((md_ctx = EVP_MD_CTX_new()) == NULL)
294 return ret;
295
296 /* Make sure X509_NAME structure contains valid cached encoding */
297 i2d_X509_NAME(x, NULL);
298 if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL) &&
299 EVP_DigestUpdate(md_ctx, x->bytes->data, x->bytes->length) &&
300 EVP_DigestFinal_ex(md_ctx, md, NULL))
301 ret = (((unsigned long)md[0]) |
302 ((unsigned long)md[1] << 8L) |
303 ((unsigned long)md[2] << 16L) |
304 ((unsigned long)md[3] << 24L)) &
305 0xffffffffL;
306
307 EVP_MD_CTX_free(md_ctx);
308
309 return ret;
310}
311LCRYPTO_ALIAS(X509_NAME_hash_old);
312#endif
313
314/* Search a stack of X509 for a match */
315X509 *
316X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
317 ASN1_INTEGER *serial)
318{
319 int i;
320 X509_CINF cinf;
321 X509 x, *x509 = NULL;
322
323 if (!sk)
324 return NULL;
325
326 x.cert_info = &cinf;
327 cinf.serialNumber = serial;
328 cinf.issuer = name;
329
330 for (i = 0; i < sk_X509_num(sk); i++) {
331 x509 = sk_X509_value(sk, i);
332 if (X509_issuer_and_serial_cmp(x509, &x) == 0)
333 return (x509);
334 }
335 return (NULL);
336}
337LCRYPTO_ALIAS(X509_find_by_issuer_and_serial);
338
339X509 *
340X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
341{
342 X509 *x509;
343 int i;
344
345 for (i = 0; i < sk_X509_num(sk); i++) {
346 x509 = sk_X509_value(sk, i);
347 if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0)
348 return (x509);
349 }
350 return (NULL);
351}
352LCRYPTO_ALIAS(X509_find_by_subject);
353
354EVP_PKEY *
355X509_get_pubkey(X509 *x)
356{
357 if (x == NULL || x->cert_info == NULL)
358 return (NULL);
359 return (X509_PUBKEY_get(x->cert_info->key));
360}
361LCRYPTO_ALIAS(X509_get_pubkey);
362
363EVP_PKEY *
364X509_get0_pubkey(const X509 *x)
365{
366 if (x == NULL || x->cert_info == NULL)
367 return (NULL);
368 return (X509_PUBKEY_get0(x->cert_info->key));
369}
370LCRYPTO_ALIAS(X509_get0_pubkey);
371
372ASN1_BIT_STRING *
373X509_get0_pubkey_bitstr(const X509 *x)
374{
375 if (!x)
376 return NULL;
377 return x->cert_info->key->public_key;
378}
379LCRYPTO_ALIAS(X509_get0_pubkey_bitstr);
380
381int
382X509_check_private_key(const X509 *x, const EVP_PKEY *k)
383{
384 const EVP_PKEY *xk;
385 int ret;
386
387 xk = X509_get0_pubkey(x);
388
389 if (xk)
390 ret = EVP_PKEY_cmp(xk, k);
391 else
392 ret = -2;
393
394 switch (ret) {
395 case 1:
396 break;
397 case 0:
398 X509error(X509_R_KEY_VALUES_MISMATCH);
399 break;
400 case -1:
401 X509error(X509_R_KEY_TYPE_MISMATCH);
402 break;
403 case -2:
404 X509error(X509_R_UNKNOWN_KEY_TYPE);
405 }
406 if (ret > 0)
407 return 1;
408 return 0;
409}
410LCRYPTO_ALIAS(X509_check_private_key);
411
412/*
413 * Not strictly speaking an "up_ref" as a STACK doesn't have a reference
414 * count but it has the same effect by duping the STACK and upping the ref of
415 * each X509 structure.
416 */
417STACK_OF(X509) *
418X509_chain_up_ref(STACK_OF(X509) *chain)
419{
420 STACK_OF(X509) *ret;
421 size_t i;
422
423 ret = sk_X509_dup(chain);
424 for (i = 0; i < sk_X509_num(ret); i++)
425 X509_up_ref(sk_X509_value(ret, i));
426
427 return ret;
428}
429LCRYPTO_ALIAS(X509_chain_up_ref);
diff --git a/src/lib/libcrypto/x509/x509_conf.c b/src/lib/libcrypto/x509/x509_conf.c
deleted file mode 100644
index e5b18c2f77..0000000000
--- a/src/lib/libcrypto/x509/x509_conf.c
+++ /dev/null
@@ -1,456 +0,0 @@
1/* $OpenBSD: x509_conf.c,v 1.29 2025/03/06 07:20:01 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2002 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 */
58/* extension creation utilities */
59
60#include <ctype.h>
61#include <stdio.h>
62#include <string.h>
63
64#include <openssl/conf.h>
65#include <openssl/err.h>
66#include <openssl/x509.h>
67#include <openssl/x509v3.h>
68
69#include "conf_local.h"
70#include "x509_local.h"
71
72static int v3_check_critical(const char **value);
73static int v3_check_generic(const char **value);
74static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int nid,
75 int crit, const char *value);
76static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value,
77 int crit, int type, X509V3_CTX *ctx);
78static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int nid,
79 int crit, void *ext_struct);
80static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx,
81 long *ext_len);
82
83X509_EXTENSION *
84X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name,
85 const char *value)
86{
87 int crit;
88 int ext_type;
89 X509_EXTENSION *ret;
90
91 crit = v3_check_critical(&value);
92 if ((ext_type = v3_check_generic(&value)))
93 return v3_generic_extension(name, value, crit, ext_type, ctx);
94 ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
95 if (!ret) {
96 X509V3error(X509V3_R_ERROR_IN_EXTENSION);
97 ERR_asprintf_error_data("name=%s, value=%s", name, value);
98 }
99 return ret;
100}
101LCRYPTO_ALIAS(X509V3_EXT_nconf);
102
103X509_EXTENSION *
104X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int nid, const char *value)
105{
106 int crit;
107 int ext_type;
108
109 crit = v3_check_critical(&value);
110 if ((ext_type = v3_check_generic(&value)))
111 return v3_generic_extension(OBJ_nid2sn(nid),
112 value, crit, ext_type, ctx);
113 return do_ext_nconf(conf, ctx, nid, crit, value);
114}
115LCRYPTO_ALIAS(X509V3_EXT_nconf_nid);
116
117static X509_EXTENSION *
118do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int nid, int crit, const char *value)
119{
120 const X509V3_EXT_METHOD *method;
121 X509_EXTENSION *ext;
122 void *ext_struct;
123
124 if (nid == NID_undef) {
125 X509V3error(X509V3_R_UNKNOWN_EXTENSION_NAME);
126 return NULL;
127 }
128 if (!(method = X509V3_EXT_get_nid(nid))) {
129 X509V3error(X509V3_R_UNKNOWN_EXTENSION);
130 return NULL;
131 }
132 /* Now get internal extension representation based on type */
133 if (method->v2i) {
134 STACK_OF(CONF_VALUE) *nval;
135
136 if (*value == '@')
137 nval = NCONF_get_section(conf, value + 1);
138 else
139 nval = X509V3_parse_list(value);
140 if (sk_CONF_VALUE_num(nval) <= 0) {
141 X509V3error(X509V3_R_INVALID_EXTENSION_STRING);
142 ERR_asprintf_error_data("name=%s,section=%s",
143 OBJ_nid2sn(nid), value);
144 if (*value != '@')
145 sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
146 return NULL;
147 }
148 ext_struct = method->v2i(method, ctx, nval);
149 if (*value != '@')
150 sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
151 } else if (method->s2i) {
152 ext_struct = method->s2i(method, ctx, value);
153 } else if (method->r2i) {
154 if (ctx->db == NULL) {
155 X509V3error(X509V3_R_NO_CONFIG_DATABASE);
156 return NULL;
157 }
158 ext_struct = method->r2i(method, ctx, value);
159 } else {
160 X509V3error(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
161 ERR_asprintf_error_data("name=%s", OBJ_nid2sn(nid));
162 return NULL;
163 }
164 if (ext_struct == NULL)
165 return NULL;
166
167 ext = do_ext_i2d(method, nid, crit, ext_struct);
168 if (method->it)
169 ASN1_item_free(ext_struct, method->it);
170 else
171 method->ext_free(ext_struct);
172 return ext;
173}
174
175static X509_EXTENSION *
176do_ext_i2d(const X509V3_EXT_METHOD *method, int nid, int crit,
177 void *ext_struct)
178{
179 unsigned char *ext_der = NULL;
180 int ext_len;
181 ASN1_OCTET_STRING *ext_oct = NULL;
182 X509_EXTENSION *ext;
183
184 /* Convert internal representation to DER */
185 if (method->it != NULL) {
186 ext_der = NULL;
187 ext_len = ASN1_item_i2d(ext_struct, &ext_der, method->it);
188 if (ext_len < 0)
189 goto err;
190 } else {
191 unsigned char *p;
192
193 if ((ext_len = method->i2d(ext_struct, NULL)) <= 0)
194 goto err;
195 if ((ext_der = calloc(1, ext_len)) == NULL)
196 goto err;
197 p = ext_der;
198 if (method->i2d(ext_struct, &p) != ext_len)
199 goto err;
200 }
201 if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL)
202 goto err;
203 ASN1_STRING_set0(ext_oct, ext_der, ext_len);
204 ext_der = NULL;
205 ext_len = 0;
206
207 ext = X509_EXTENSION_create_by_NID(NULL, nid, crit, ext_oct);
208 if (ext == NULL)
209 goto err;
210 ASN1_OCTET_STRING_free(ext_oct);
211
212 return ext;
213
214 err:
215 free(ext_der);
216 ASN1_OCTET_STRING_free(ext_oct);
217 X509V3error(ERR_R_MALLOC_FAILURE);
218
219 return NULL;
220}
221
222/* Given an internal structure, nid and critical flag create an extension */
223X509_EXTENSION *
224X509V3_EXT_i2d(int nid, int crit, void *ext_struct)
225{
226 const X509V3_EXT_METHOD *method;
227
228 if (!(method = X509V3_EXT_get_nid(nid))) {
229 X509V3error(X509V3_R_UNKNOWN_EXTENSION);
230 return NULL;
231 }
232 return do_ext_i2d(method, nid, crit, ext_struct);
233}
234LCRYPTO_ALIAS(X509V3_EXT_i2d);
235
236/* Check the extension string for critical flag */
237static int
238v3_check_critical(const char **value)
239{
240 const char *p = *value;
241
242 if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
243 return 0;
244 p += 9;
245 while (isspace((unsigned char)*p)) p++;
246 *value = p;
247 return 1;
248}
249
250/* Check extension string for generic extension and return the type */
251static int
252v3_check_generic(const char **value)
253{
254 int gen_type = 0;
255 const char *p = *value;
256
257 if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) {
258 p += 4;
259 gen_type = 1;
260 } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) {
261 p += 5;
262 gen_type = 2;
263 } else
264 return 0;
265
266 while (isspace((unsigned char)*p))
267 p++;
268 *value = p;
269 return gen_type;
270}
271
272/* Create a generic extension: for now just handle DER type */
273static X509_EXTENSION *
274v3_generic_extension(const char *name, const char *value, int crit, int gen_type,
275 X509V3_CTX *ctx)
276{
277 unsigned char *ext_der = NULL;
278 long ext_len = 0;
279 ASN1_OBJECT *obj = NULL;
280 ASN1_OCTET_STRING *oct = NULL;
281 X509_EXTENSION *ext = NULL;
282
283 if ((obj = OBJ_txt2obj(name, 0)) == NULL) {
284 X509V3error(X509V3_R_EXTENSION_NAME_ERROR);
285 ERR_asprintf_error_data("name=%s", name);
286 goto err;
287 }
288
289 if (gen_type == 1)
290 ext_der = string_to_hex(value, &ext_len);
291 else if (gen_type == 2)
292 ext_der = generic_asn1(value, ctx, &ext_len);
293 else {
294 ERR_asprintf_error_data("Unexpected generic extension type %d", gen_type);
295 goto err;
296 }
297
298 if (ext_der == NULL) {
299 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
300 ERR_asprintf_error_data("value=%s", value);
301 goto err;
302 }
303
304 if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
305 X509V3error(ERR_R_MALLOC_FAILURE);
306 goto err;
307 }
308
309 ASN1_STRING_set0(oct, ext_der, ext_len);
310 ext_der = NULL;
311 ext_len = 0;
312
313 ext = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
314
315 err:
316 ASN1_OBJECT_free(obj);
317 ASN1_OCTET_STRING_free(oct);
318 free(ext_der);
319
320 return ext;
321}
322
323static unsigned char *
324generic_asn1(const char *value, X509V3_CTX *ctx, long *ext_len)
325{
326 ASN1_TYPE *typ;
327 unsigned char *ext_der = NULL;
328
329 typ = ASN1_generate_v3(value, ctx);
330 if (typ == NULL)
331 return NULL;
332 *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
333 ASN1_TYPE_free(typ);
334 return ext_der;
335}
336
337/*
338 * This is the main function: add a bunch of extensions based on a config file
339 * section to an extension STACK.
340 */
341
342int
343X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
344 STACK_OF(X509_EXTENSION) **sk)
345{
346 X509_EXTENSION *ext;
347 STACK_OF(CONF_VALUE) *nval;
348 CONF_VALUE *val;
349 int i;
350
351 if (!(nval = NCONF_get_section(conf, section)))
352 return 0;
353 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
354 val = sk_CONF_VALUE_value(nval, i);
355 if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
356 return 0;
357 if (sk)
358 X509v3_add_ext(sk, ext, -1);
359 X509_EXTENSION_free(ext);
360 }
361 return 1;
362}
363LCRYPTO_ALIAS(X509V3_EXT_add_nconf_sk);
364
365int
366X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
367 X509 *cert)
368{
369 STACK_OF(X509_EXTENSION) **sk = NULL;
370
371 if (cert)
372 sk = &cert->cert_info->extensions;
373 return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
374}
375LCRYPTO_ALIAS(X509V3_EXT_add_nconf);
376
377int
378X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
379 X509_CRL *crl)
380{
381 STACK_OF(X509_EXTENSION) **sk = NULL;
382
383 if (crl)
384 sk = &crl->crl->extensions;
385 return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
386}
387LCRYPTO_ALIAS(X509V3_EXT_CRL_add_nconf);
388
389int
390X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
391 X509_REQ *req)
392{
393 STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
394 int i;
395
396 if (req)
397 sk = &extlist;
398 i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
399 if (!i || !sk)
400 return i;
401 i = X509_REQ_add_extensions(req, extlist);
402 sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
403 return i;
404}
405LCRYPTO_ALIAS(X509V3_EXT_REQ_add_nconf);
406
407STACK_OF(CONF_VALUE) *
408X509V3_get0_section(X509V3_CTX *ctx, const char *section)
409{
410 if (ctx->db == NULL) {
411 X509V3error(X509V3_R_OPERATION_NOT_DEFINED);
412 return NULL;
413 }
414 return NCONF_get_section(ctx->db, section);
415}
416
417void
418X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
419{
420 ctx->db = conf;
421}
422LCRYPTO_ALIAS(X509V3_set_nconf);
423
424void
425X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
426 X509_CRL *crl, int flags)
427{
428 ctx->issuer_cert = issuer;
429 ctx->subject_cert = subj;
430 ctx->crl = crl;
431 ctx->subject_req = req;
432 ctx->flags = flags;
433}
434LCRYPTO_ALIAS(X509V3_set_ctx);
435
436X509_EXTENSION *
437X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, const char *name,
438 const char *value)
439{
440 CONF ctmp;
441
442 CONF_set_nconf(&ctmp, conf);
443 return X509V3_EXT_nconf(&ctmp, ctx, name, value);
444}
445LCRYPTO_ALIAS(X509V3_EXT_conf);
446
447X509_EXTENSION *
448X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int nid,
449 const char *value)
450{
451 CONF ctmp;
452
453 CONF_set_nconf(&ctmp, conf);
454 return X509V3_EXT_nconf_nid(&ctmp, ctx, nid, value);
455}
456LCRYPTO_ALIAS(X509V3_EXT_conf_nid);
diff --git a/src/lib/libcrypto/x509/x509_constraints.c b/src/lib/libcrypto/x509/x509_constraints.c
deleted file mode 100644
index 0773d2ba71..0000000000
--- a/src/lib/libcrypto/x509/x509_constraints.c
+++ /dev/null
@@ -1,1294 +0,0 @@
1/* $OpenBSD: x509_constraints.c,v 1.32 2023/09/29 15:53:59 beck Exp $ */
2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <ctype.h>
19#include <errno.h>
20#include <stdio.h>
21#include <string.h>
22#include <time.h>
23#include <unistd.h>
24
25#include <sys/socket.h>
26#include <arpa/inet.h>
27
28#include <openssl/safestack.h>
29#include <openssl/x509.h>
30#include <openssl/x509v3.h>
31
32#include "bytestring.h"
33#include "x509_internal.h"
34
35/* RFC 2821 section 4.5.3.1 */
36#define LOCAL_PART_MAX_LEN (size_t)64
37#define DOMAIN_PART_MAX_LEN (size_t)255
38#define MAX_IP_ADDRESS_LENGTH (size_t)46
39
40static int
41cbs_is_ip_address(CBS *cbs, int *is_ip)
42{
43 struct sockaddr_in6 sin6;
44 struct sockaddr_in sin4;
45 char *name = NULL;
46
47 *is_ip = 0;
48 if (CBS_len(cbs) > MAX_IP_ADDRESS_LENGTH)
49 return 1;
50 if (!CBS_strdup(cbs, &name))
51 return 0;
52 if (inet_pton(AF_INET, name, &sin4) == 1 ||
53 inet_pton(AF_INET6, name, &sin6) == 1)
54 *is_ip = 1;
55
56 free(name);
57 return 1;
58}
59
60struct x509_constraints_name *
61x509_constraints_name_new(void)
62{
63 return (calloc(1, sizeof(struct x509_constraints_name)));
64}
65
66void
67x509_constraints_name_clear(struct x509_constraints_name *name)
68{
69 free(name->name);
70 free(name->local);
71 free(name->der);
72 memset(name, 0, sizeof(*name));
73}
74
75void
76x509_constraints_name_free(struct x509_constraints_name *name)
77{
78 if (name == NULL)
79 return;
80 x509_constraints_name_clear(name);
81 free(name);
82}
83
84struct x509_constraints_name *
85x509_constraints_name_dup(struct x509_constraints_name *name)
86{
87 struct x509_constraints_name *new;
88
89 if ((new = x509_constraints_name_new()) == NULL)
90 goto err;
91 new->type = name->type;
92 new->af = name->af;
93 new->der_len = name->der_len;
94 if (name->der_len > 0) {
95 if ((new->der = malloc(name->der_len)) == NULL)
96 goto err;
97 memcpy(new->der, name->der, name->der_len);
98 }
99 if (name->name != NULL && (new->name = strdup(name->name)) == NULL)
100 goto err;
101 if (name->local != NULL && (new->local = strdup(name->local)) == NULL)
102 goto err;
103 memcpy(new->address, name->address, sizeof(name->address));
104 return new;
105 err:
106 x509_constraints_name_free(new);
107 return NULL;
108}
109
110struct x509_constraints_names *
111x509_constraints_names_new(size_t names_max)
112{
113 struct x509_constraints_names *new;
114
115 if ((new = calloc(1, sizeof(struct x509_constraints_names))) == NULL)
116 return NULL;
117
118 new->names_max = names_max;
119
120 return new;
121}
122
123void
124x509_constraints_names_clear(struct x509_constraints_names *names)
125{
126 size_t i;
127
128 for (i = 0; i < names->names_count; i++)
129 x509_constraints_name_free(names->names[i]);
130 free(names->names);
131 memset(names, 0, sizeof(*names));
132}
133
134void
135x509_constraints_names_free(struct x509_constraints_names *names)
136{
137 if (names == NULL)
138 return;
139
140 x509_constraints_names_clear(names);
141 free(names);
142}
143
144int
145x509_constraints_names_add(struct x509_constraints_names *names,
146 struct x509_constraints_name *name)
147{
148 if (names->names_count >= names->names_max)
149 return 0;
150 if (names->names_count == names->names_len) {
151 struct x509_constraints_name **tmp;
152 if ((tmp = recallocarray(names->names, names->names_len,
153 names->names_len + 32, sizeof(*tmp))) == NULL)
154 return 0;
155 names->names_len += 32;
156 names->names = tmp;
157 }
158 names->names[names->names_count] = name;
159 names->names_count++;
160 return 1;
161}
162
163struct x509_constraints_names *
164x509_constraints_names_dup(struct x509_constraints_names *names)
165{
166 struct x509_constraints_names *new = NULL;
167 struct x509_constraints_name *name = NULL;
168 size_t i;
169
170 if (names == NULL)
171 return NULL;
172
173 if ((new = x509_constraints_names_new(names->names_max)) == NULL)
174 goto err;
175
176 for (i = 0; i < names->names_count; i++) {
177 if ((name = x509_constraints_name_dup(names->names[i])) == NULL)
178 goto err;
179 if (!x509_constraints_names_add(new, name))
180 goto err;
181 }
182
183 return new;
184 err:
185 x509_constraints_names_free(new);
186 x509_constraints_name_free(name);
187 return NULL;
188}
189
190/*
191 * Validate that the name contains only a hostname consisting of RFC
192 * 5890 compliant A-labels (see RFC 6066 section 3). This is more
193 * permissive to allow for a leading '.' for a subdomain based
194 * constraint, as well as allowing for '_' which is commonly accepted
195 * by nonconformant DNS implementations.
196 *
197 * if "wildcards" is set it allows '*' to occur in the string at the end of a
198 * component.
199 */
200static int
201x509_constraints_valid_domain_internal(CBS *cbs, int wildcards)
202{
203 int first, component = 0;
204 uint8_t prev, c = 0;
205 size_t i, len;
206 CBS copy;
207
208 CBS_dup(cbs, &copy);
209
210 len = CBS_len(cbs);
211
212 if (len > DOMAIN_PART_MAX_LEN)
213 return 0;
214 for (i = 0; i < len; i++) {
215 prev = c;
216 if (!CBS_get_u8(&copy, &c))
217 return 0;
218
219 first = (i == 0);
220
221 /* Everything has to be ASCII, with no NUL byte */
222 if (!isascii(c) || c == '\0')
223 return 0;
224 /* It must be alphanumeric, a '-', '.', '_' or '*' */
225 if (!isalnum(c) && c != '-' && c != '.' && c != '_' && c != '*')
226 return 0;
227
228 /* if it is a '*', fail if not wildcards */
229 if (!wildcards && c == '*')
230 return 0;
231
232 /* '-' must not start a component or be at the end. */
233 if (c == '-' && (component == 0 || i == len - 1))
234 return 0;
235
236 /*
237 * '.' must not be at the end. It may be first overall
238 * but must not otherwise start a component.
239 */
240 if (c == '.' && ((component == 0 && !first) || i == len - 1))
241 return 0;
242
243 if (c == '.') {
244 /* Components can not end with a dash. */
245 if (prev == '-')
246 return 0;
247 /* Start new component */
248 component = 0;
249 continue;
250 }
251 /*
252 * Wildcards can only occur at the end of a component.
253 * c*.com is valid, c*c.com is not.
254 */
255 if (prev == '*')
256 return 0;
257
258 /* Components must be 63 chars or less. */
259 if (++component > 63)
260 return 0;
261 }
262
263 return 1;
264}
265
266int
267x509_constraints_valid_host(CBS *cbs, int permit_ip)
268{
269 uint8_t first;
270 int is_ip;
271
272 if (!CBS_peek_u8(cbs, &first))
273 return 0;
274 if (first == '.')
275 return 0; /* leading . not allowed in a host name or IP */
276 if (!permit_ip) {
277 if (!cbs_is_ip_address(cbs, &is_ip))
278 return 0;
279 if (is_ip)
280 return 0;
281 }
282
283 return x509_constraints_valid_domain_internal(cbs, 0);
284}
285
286int
287x509_constraints_valid_sandns(CBS *cbs)
288{
289 uint8_t first;
290
291 if (!CBS_peek_u8(cbs, &first))
292 return 0;
293 if (first == '.')
294 return 0; /* leading . not allowed in a SAN DNS name */
295 /*
296 * A domain may not be less than two characters, so you
297 * can't wildcard a single domain of less than that
298 */
299 if (CBS_len(cbs) < 4 && first == '*')
300 return 0;
301
302 return x509_constraints_valid_domain_internal(cbs, 1);
303}
304
305static inline int
306local_part_ok(char c)
307{
308 return (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') ||
309 ('A' <= c && c <= 'Z') || c == '!' || c == '#' || c == '$' ||
310 c == '%' || c == '&' || c == '\'' || c == '*' || c == '+' ||
311 c == '-' || c == '/' || c == '=' || c == '?' || c == '^' ||
312 c == '_' || c == '`' || c == '{' || c == '|' || c == '}' ||
313 c == '~' || c == '.');
314}
315
316/*
317 * Parse "candidate" as an RFC 2821 mailbox.
318 * Returns 0 if candidate is not a valid mailbox or if an error occurs.
319 * Returns 1 if candidate is a mailbox and adds newly allocated
320 * local and domain parts of the mailbox to "name->local" and name->name"
321 */
322int
323x509_constraints_parse_mailbox(CBS *candidate,
324 struct x509_constraints_name *name)
325{
326 char working[DOMAIN_PART_MAX_LEN + 1] = { 0 };
327 char *candidate_local = NULL;
328 char *candidate_domain = NULL;
329 CBS domain_cbs;
330 size_t i, len, wi = 0;
331 int accept = 0;
332 int quoted = 0;
333 CBS copy;
334
335 /* XXX This should not be necessary - revisit and remove */
336 if (candidate == NULL)
337 return 0;
338
339 CBS_dup(candidate, &copy);
340
341 if ((len = CBS_len(&copy)) == 0)
342 return 0;
343
344 /* It can't be bigger than the local part, domain part and the '@' */
345 if (len > LOCAL_PART_MAX_LEN + DOMAIN_PART_MAX_LEN + 1)
346 return 0;
347
348 for (i = 0; i < len; i++) {
349 char c;
350 if (!CBS_get_u8(&copy, &c))
351 goto bad;
352 /* non ascii, cr, lf, or nul is never allowed */
353 if (!isascii(c) || c == '\r' || c == '\n' || c == '\0')
354 goto bad;
355 if (i == 0) {
356 /* local part is quoted part */
357 if (c == '"')
358 quoted = 1;
359 /* can not start with a . */
360 if (c == '.')
361 goto bad;
362 }
363 if (accept) {
364 if (wi >= DOMAIN_PART_MAX_LEN)
365 goto bad;
366 working[wi++] = c;
367 accept = 0;
368 continue;
369 }
370 if (candidate_local != NULL) {
371 /* We are looking for the domain part */
372 if (wi >= DOMAIN_PART_MAX_LEN)
373 goto bad;
374 working[wi++] = c;
375 if (i == len - 1) {
376 if (wi == 0)
377 goto bad;
378 if (candidate_domain != NULL)
379 goto bad;
380 candidate_domain = strdup(working);
381 if (candidate_domain == NULL)
382 goto bad;
383 }
384 continue;
385 }
386 /* We are looking for the local part */
387 if (wi >= LOCAL_PART_MAX_LEN)
388 break;
389
390 if (quoted) {
391 if (c == '\\') {
392 accept = 1;
393 continue;
394 }
395 if (c == '"' && i != 0) {
396 uint8_t next;
397 /* end the quoted part. @ must be next */
398 if (!CBS_peek_u8(&copy, &next))
399 goto bad;
400 if (next != '@')
401 goto bad;
402 quoted = 0;
403 }
404 /*
405 * XXX Go strangely permits sp but forbids ht
406 * mimic that for now
407 */
408 if (c == 9)
409 goto bad;
410 if (wi >= LOCAL_PART_MAX_LEN)
411 goto bad;
412 working[wi++] = c;
413 continue; /* all's good inside our quoted string */
414 }
415 if (c == '@') {
416 if (wi == 0)
417 goto bad;
418 if (candidate_local != NULL)
419 goto bad;
420 candidate_local = strdup(working);
421 if (candidate_local == NULL)
422 goto bad;
423 memset(working, 0, sizeof(working));
424 wi = 0;
425 continue;
426 }
427 if (c == '\\') {
428 uint8_t next;
429 /*
430 * RFC 2821 hints these can happen outside of
431 * quoted string. Don't include the \ but
432 * next character must be ok.
433 */
434 if (!CBS_peek_u8(&copy, &next))
435 goto bad;
436 if (!local_part_ok(next))
437 goto bad;
438 accept = 1;
439 }
440 if (!local_part_ok(c))
441 goto bad;
442 if (wi >= LOCAL_PART_MAX_LEN)
443 goto bad;
444 working[wi++] = c;
445 }
446 if (candidate_local == NULL || candidate_domain == NULL)
447 goto bad;
448 CBS_init(&domain_cbs, candidate_domain, strlen(candidate_domain));
449 if (!x509_constraints_valid_host(&domain_cbs, 0))
450 goto bad;
451
452 if (name != NULL) {
453 name->local = candidate_local;
454 name->name = candidate_domain;
455 name->type = GEN_EMAIL;
456 } else {
457 free(candidate_local);
458 free(candidate_domain);
459 }
460 return 1;
461 bad:
462 free(candidate_local);
463 free(candidate_domain);
464 return 0;
465}
466
467int
468x509_constraints_valid_domain_constraint(CBS *cbs)
469{
470 uint8_t first;
471
472 if (CBS_len(cbs) == 0)
473 return 1; /* empty constraints match */
474
475 /*
476 * A domain may not be less than two characters, so you
477 * can't match a single domain of less than that
478 */
479 if (CBS_len(cbs) < 3) {
480 if (!CBS_peek_u8(cbs, &first))
481 return 0;
482 if (first == '.')
483 return 0;
484 }
485 return x509_constraints_valid_domain_internal(cbs, 0);
486}
487
488/*
489 * Extract the host part of a URI. On failure to parse a valid host part of the
490 * URI, 0 is returned indicating an invalid URI. If the host part parses as
491 * valid, or is not present, 1 is returned indicating a possibly valid URI.
492 *
493 * In the case of a valid URI, *hostpart will be set to a copy of the host part
494 * of the URI, or the empty string if no URI is present. If memory allocation
495 * fails *hostpart will be set to NULL, even though we returned 1. It is the
496 * caller's responsibility to indicate an error for memory allocation failure,
497 * and the callers responsibility to free *hostpart.
498 *
499 * RFC 3986:
500 * the authority part of a uri starts with // and is terminated with
501 * the next '/', '?', '#' or end of the URI.
502 *
503 * The authority itself contains [userinfo '@'] host [: port]
504 *
505 * so the host starts at the start or after the '@', and ends
506 * with end of URI, '/', '?', "#', or ':'.
507 */
508int
509x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostpart)
510{
511 size_t i, hostlen = 0;
512 uint8_t *authority = NULL;
513 char *host = NULL;
514 CBS host_cbs;
515
516 /*
517 * Find first '//'. there must be at least a '//' and
518 * something else.
519 */
520 if (len < 3)
521 return 0;
522 for (i = 0; i < len - 1; i++) {
523 if (!isascii(uri[i]))
524 return 0;
525 if (uri[i] == '/' && uri[i + 1] == '/') {
526 authority = uri + i + 2;
527 break;
528 }
529 }
530 if (authority == NULL) {
531 /*
532 * There is no authority, so no host part in this
533 * URI. This might be ok or might not, but it must
534 * fail if we run into a name constraint later, so
535 * we indicate that we have a URI with an empty
536 * host part, and succeed.
537 */
538 if (hostpart != NULL)
539 *hostpart = strdup("");
540 return 1;
541 }
542 for (i = authority - uri; i < len; i++) {
543 if (!isascii(uri[i]))
544 return 0;
545 /* it has a userinfo part */
546 if (uri[i] == '@') {
547 hostlen = 0;
548 /* it can only have one */
549 if (host != NULL)
550 break;
551 /* start after the userinfo part */
552 host = uri + i + 1;
553 continue;
554 }
555 /* did we find the end? */
556 if (uri[i] == ':' || uri[i] == '/' || uri[i] == '?' ||
557 uri[i] == '#')
558 break;
559 hostlen++;
560 }
561 if (hostlen == 0)
562 return 0;
563 if (host == NULL)
564 host = authority;
565 CBS_init(&host_cbs, host, hostlen);
566 if (!x509_constraints_valid_host(&host_cbs, 1))
567 return 0;
568 if (hostpart != NULL && !CBS_strdup(&host_cbs, hostpart))
569 return 0;
570 return 1;
571}
572
573int
574x509_constraints_sandns(char *sandns, size_t dlen, char *constraint, size_t len)
575{
576 char *suffix;
577
578 if (len == 0)
579 return 1; /* an empty constraint matches everything */
580
581 /* match the end of the domain */
582 if (dlen < len)
583 return 0;
584 suffix = sandns + (dlen - len);
585 return (strncasecmp(suffix, constraint, len) == 0);
586}
587
588/*
589 * Validate a pre-validated domain of length dlen against a pre-validated
590 * constraint of length len.
591 *
592 * returns 1 if the domain and constraint match.
593 * returns 0 otherwise.
594 *
595 * an empty constraint matches everything.
596 * constraint will be matched against the domain as a suffix if it
597 * starts with a '.'.
598 * domain will be matched against the constraint as a suffix if it
599 * starts with a '.'.
600 */
601int
602x509_constraints_domain(char *domain, size_t dlen, char *constraint, size_t len)
603{
604 if (len == 0)
605 return 1; /* an empty constraint matches everything */
606
607 if (constraint[0] == '.') {
608 /* match the end of the domain */
609 char *suffix;
610 if (dlen < len)
611 return 0;
612 suffix = domain + (dlen - len);
613 return (strncasecmp(suffix, constraint, len) == 0);
614 }
615 if (domain[0] == '.') {
616 /* match the end of the constraint */
617 char *suffix;
618 if (len < dlen)
619 return 0;
620 suffix = constraint + (len - dlen);
621 return (strncasecmp(suffix, domain, dlen) == 0);
622 }
623 /* otherwise we must exactly match the constraint */
624 if (dlen != len)
625 return 0;
626 return (strncasecmp(domain, constraint, len) == 0);
627}
628
629int
630x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint,
631 size_t len,
632 int *error)
633{
634 int ret = 0;
635 char *hostpart = NULL;
636 CBS cbs;
637
638 CBS_init(&cbs, constraint, len);
639 if (!x509_constraints_uri_host(uri, ulen, &hostpart)) {
640 *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
641 goto err;
642 }
643 if (hostpart == NULL) {
644 *error = X509_V_ERR_OUT_OF_MEM;
645 goto err;
646 }
647 if (!x509_constraints_valid_domain_constraint(&cbs)) {
648 *error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX;
649 goto err;
650 }
651 ret = x509_constraints_domain(hostpart, strlen(hostpart), constraint,
652 len);
653 err:
654 free(hostpart);
655 return ret;
656}
657
658/*
659 * Verify a validated address of size alen with a validated constraint
660 * of size constraint_len. returns 1 if matching, 0 if not.
661 * Addresses are assumed to be pre-validated for a length of 4 and 8
662 * respectively for ipv4 addresses and constraints, and a length of
663 * 16 and 32 respectively for ipv6 address constraints by the caller.
664 */
665int
666x509_constraints_ipaddr(uint8_t *address, size_t alen, uint8_t *constraint,
667 size_t len)
668{
669 uint8_t *mask;
670 size_t i;
671
672 if (alen * 2 != len)
673 return 0;
674
675 mask = constraint + alen;
676 for (i = 0; i < alen; i++) {
677 if ((address[i] & mask[i]) != (constraint[i] & mask[i]))
678 return 0;
679 }
680 return 1;
681}
682
683/*
684 * Verify a canonicalized der encoded constraint dirname
685 * a canonicalized der encoded constraint.
686 */
687int
688x509_constraints_dirname(uint8_t *dirname, size_t dlen,
689 uint8_t *constraint, size_t len)
690{
691 /*
692 * The constraint must be a prefix in DER format, so it can't be
693 * longer than the name it is checked against.
694 */
695 if (len > dlen)
696 return 0;
697 return (memcmp(constraint, dirname, len) == 0);
698}
699
700/*
701 * De-obfuscate a GENERAL_NAME into useful bytes for a name or constraint.
702 */
703int
704x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes,
705 size_t *len)
706{
707 *bytes = NULL;
708 *len = 0;
709
710 if (name->type == GEN_DNS) {
711 ASN1_IA5STRING *aname = name->d.dNSName;
712
713 *bytes = aname->data;
714 *len = aname->length;
715
716 return name->type;
717 }
718 if (name->type == GEN_EMAIL) {
719 ASN1_IA5STRING *aname = name->d.rfc822Name;
720
721 *bytes = aname->data;
722 *len = aname->length;
723
724 return name->type;
725 }
726 if (name->type == GEN_URI) {
727 ASN1_IA5STRING *aname = name->d.uniformResourceIdentifier;
728
729 *bytes = aname->data;
730 *len = aname->length;
731
732 return name->type;
733 }
734 if (name->type == GEN_DIRNAME) {
735 X509_NAME *dname = name->d.directoryName;
736
737 if (!dname->modified || i2d_X509_NAME(dname, NULL) >= 0) {
738 *bytes = dname->canon_enc;
739 *len = dname->canon_enclen;
740
741 return name->type;
742 }
743 }
744 if (name->type == GEN_IPADD) {
745 *bytes = name->d.ip->data;
746 *len = name->d.ip->length;
747
748 return name->type;
749 }
750
751 return 0;
752}
753
754/*
755 * Extract the relevant names for constraint checking from "cert",
756 * validate them, and add them to the list of cert names for "chain".
757 * returns 1 on success sets error and returns 0 on failure.
758 */
759int
760x509_constraints_extract_names(struct x509_constraints_names *names,
761 X509 *cert, int is_leaf, int *error)
762{
763 struct x509_constraints_name *vname = NULL;
764 X509_NAME *subject_name;
765 GENERAL_NAME *name;
766 ssize_t i = 0;
767 int name_type, include_cn = is_leaf, include_email = is_leaf;
768
769 /* first grab the altnames */
770 while ((name = sk_GENERAL_NAME_value(cert->altname, i++)) != NULL) {
771 uint8_t *bytes = NULL;
772 size_t len = 0;
773 CBS cbs;
774
775 if ((vname = x509_constraints_name_new()) == NULL) {
776 *error = X509_V_ERR_OUT_OF_MEM;
777 goto err;
778 }
779
780 name_type = x509_constraints_general_to_bytes(name, &bytes,
781 &len);
782 CBS_init(&cbs, bytes, len);
783 switch (name_type) {
784 case GEN_DNS:
785 if (!x509_constraints_valid_sandns(&cbs)) {
786 *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
787 goto err;
788 }
789 if (!CBS_strdup(&cbs, &vname->name)) {
790 *error = X509_V_ERR_OUT_OF_MEM;
791 goto err;
792 }
793 vname->type = GEN_DNS;
794 include_cn = 0; /* Don't use cn from subject */
795 break;
796 case GEN_EMAIL:
797 if (!x509_constraints_parse_mailbox(&cbs, vname)) {
798 *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
799 goto err;
800 }
801 vname->type = GEN_EMAIL;
802 include_email = 0; /* Don't use email from subject */
803 break;
804 case GEN_URI:
805 if (!x509_constraints_uri_host(bytes, len,
806 &vname->name)) {
807 *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
808 goto err;
809 }
810 if (vname->name == NULL) {
811 *error = X509_V_ERR_OUT_OF_MEM;
812 goto err;
813 }
814 vname->type = GEN_URI;
815 break;
816 case GEN_DIRNAME:
817 if (len == 0) {
818 *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
819 goto err;
820 }
821 if (bytes == NULL || ((vname->der = malloc(len)) ==
822 NULL)) {
823 *error = X509_V_ERR_OUT_OF_MEM;
824 goto err;
825 }
826 memcpy(vname->der, bytes, len);
827 vname->der_len = len;
828 vname->type = GEN_DIRNAME;
829 break;
830 case GEN_IPADD:
831 if (len == 4)
832 vname->af = AF_INET;
833 if (len == 16)
834 vname->af = AF_INET6;
835 if (vname->af != AF_INET && vname->af != AF_INET6) {
836 *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
837 goto err;
838 }
839 memcpy(vname->address, bytes, len);
840 vname->type = GEN_IPADD;
841 break;
842 default:
843 /* Ignore this name */
844 x509_constraints_name_free(vname);
845 vname = NULL;
846 continue;
847 }
848 if (!x509_constraints_names_add(names, vname)) {
849 *error = X509_V_ERR_OUT_OF_MEM;
850 goto err;
851 }
852 vname = NULL;
853 }
854
855 x509_constraints_name_free(vname);
856 vname = NULL;
857
858 subject_name = X509_get_subject_name(cert);
859 if (X509_NAME_entry_count(subject_name) > 0) {
860 X509_NAME_ENTRY *email;
861 X509_NAME_ENTRY *cn;
862 /*
863 * This cert has a non-empty subject, so we must add
864 * the subject as a dirname to be compared against
865 * any dirname constraints
866 */
867 if ((subject_name->modified &&
868 i2d_X509_NAME(subject_name, NULL) < 0) ||
869 (vname = x509_constraints_name_new()) == NULL ||
870 (vname->der = malloc(subject_name->canon_enclen)) == NULL) {
871 *error = X509_V_ERR_OUT_OF_MEM;
872 goto err;
873 }
874
875 memcpy(vname->der, subject_name->canon_enc,
876 subject_name->canon_enclen);
877 vname->der_len = subject_name->canon_enclen;
878 vname->type = GEN_DIRNAME;
879 if (!x509_constraints_names_add(names, vname)) {
880 *error = X509_V_ERR_OUT_OF_MEM;
881 goto err;
882 }
883 vname = NULL;
884 /*
885 * Get any email addresses from the subject line, and
886 * add them as mbox names to be compared against any
887 * email constraints
888 */
889 while (include_email &&
890 (i = X509_NAME_get_index_by_NID(subject_name,
891 NID_pkcs9_emailAddress, i)) >= 0) {
892 ASN1_STRING *aname;
893 CBS cbs;
894 if ((email = X509_NAME_get_entry(subject_name, i)) ==
895 NULL ||
896 (aname = X509_NAME_ENTRY_get_data(email)) == NULL) {
897 *error = X509_V_ERR_OUT_OF_MEM;
898 goto err;
899 }
900 CBS_init(&cbs, aname->data, aname->length);
901 if ((vname = x509_constraints_name_new()) == NULL) {
902 *error = X509_V_ERR_OUT_OF_MEM;
903 goto err;
904 }
905 if (!x509_constraints_parse_mailbox(&cbs, vname)) {
906 *error = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
907 goto err;
908 }
909 vname->type = GEN_EMAIL;
910 if (!x509_constraints_names_add(names, vname)) {
911 *error = X509_V_ERR_OUT_OF_MEM;
912 goto err;
913 }
914 vname = NULL;
915 }
916 /*
917 * Include the CN as a hostname to be checked against
918 * name constraints if it looks like a hostname.
919 */
920 while (include_cn &&
921 (i = X509_NAME_get_index_by_NID(subject_name,
922 NID_commonName, i)) >= 0) {
923 CBS cbs;
924 ASN1_STRING *aname;
925 if ((cn = X509_NAME_get_entry(subject_name, i)) ==
926 NULL ||
927 (aname = X509_NAME_ENTRY_get_data(cn)) == NULL) {
928 *error = X509_V_ERR_OUT_OF_MEM;
929 goto err;
930 }
931 CBS_init(&cbs, aname->data, aname->length);
932 if (!x509_constraints_valid_host(&cbs, 0))
933 continue; /* ignore it if not a hostname */
934 if ((vname = x509_constraints_name_new()) == NULL) {
935 *error = X509_V_ERR_OUT_OF_MEM;
936 goto err;
937 }
938 if (!CBS_strdup(&cbs, &vname->name)) {
939 *error = X509_V_ERR_OUT_OF_MEM;
940 goto err;
941 }
942 vname->type = GEN_DNS;
943 if (!x509_constraints_names_add(names, vname)) {
944 *error = X509_V_ERR_OUT_OF_MEM;
945 goto err;
946 }
947 vname = NULL;
948 }
949 }
950 return 1;
951 err:
952 x509_constraints_name_free(vname);
953 return 0;
954}
955
956/*
957 * Validate a constraint in a general name, putting the relevant data
958 * into "name" if valid. returns 0, and sets error if the constraint is
959 * not valid. returns 1 if the constraint validated. name->type will be
960 * set to a valid type if there is constraint data in name, or unmodified
961 * if the GENERAL_NAME had a valid type but was ignored.
962 */
963int
964x509_constraints_validate(GENERAL_NAME *constraint,
965 struct x509_constraints_name **out_name, int *out_error)
966{
967 uint8_t next, *bytes = NULL;
968 size_t len = 0;
969 struct x509_constraints_name *name;
970 int error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX;
971 int name_type;
972 CBS cbs;
973
974 if (out_name == NULL || *out_name != NULL)
975 return 0;
976
977 if (out_error != NULL)
978 *out_error = 0;
979
980 if ((name = x509_constraints_name_new()) == NULL) {
981 error = X509_V_ERR_OUT_OF_MEM;
982 goto err;
983 }
984
985 name_type = x509_constraints_general_to_bytes(constraint, &bytes, &len);
986 CBS_init(&cbs, bytes, len);
987 switch (name_type) {
988 case GEN_DIRNAME:
989 if (len == 0)
990 goto err; /* XXX The RFCs are delightfully vague */
991 if (bytes == NULL || (name->der = malloc(len)) == NULL) {
992 error = X509_V_ERR_OUT_OF_MEM;
993 goto err;
994 }
995 memcpy(name->der, bytes, len);
996 name->der_len = len;
997 name->type = GEN_DIRNAME;
998 break;
999 case GEN_DNS:
1000 if (!x509_constraints_valid_domain_constraint(&cbs))
1001 goto err;
1002 if ((name->name = strndup(bytes, len)) == NULL) {
1003 error = X509_V_ERR_OUT_OF_MEM;
1004 goto err;
1005 }
1006 name->type = GEN_DNS;
1007 break;
1008 case GEN_EMAIL:
1009 if (len > 0 && memchr(bytes + 1, '@', len - 1) != NULL) {
1010 if (!x509_constraints_parse_mailbox(&cbs, name))
1011 goto err;
1012 break;
1013 }
1014 /*
1015 * Mail constraints of the form @domain.com are accepted by
1016 * OpenSSL and Microsoft.
1017 */
1018 if (CBS_len(&cbs) > 0) {
1019 if (!CBS_peek_u8(&cbs, &next))
1020 goto err;
1021 if (next == '@') {
1022 if (!CBS_skip(&cbs, 1))
1023 goto err;
1024 }
1025 }
1026 if (!x509_constraints_valid_domain_constraint(&cbs))
1027 goto err;
1028 if (!CBS_strdup(&cbs, &name->name)) {
1029 error = X509_V_ERR_OUT_OF_MEM;
1030 goto err;
1031 }
1032 name->type = GEN_EMAIL;
1033 break;
1034 case GEN_IPADD:
1035 /* Constraints are ip then mask */
1036 if (len == 8)
1037 name->af = AF_INET;
1038 else if (len == 32)
1039 name->af = AF_INET6;
1040 else
1041 goto err;
1042 memcpy(&name->address[0], bytes, len);
1043 name->type = GEN_IPADD;
1044 break;
1045 case GEN_URI:
1046 if (!x509_constraints_valid_domain_constraint(&cbs))
1047 goto err;
1048 if ((name->name = strndup(bytes, len)) == NULL) {
1049 error = X509_V_ERR_OUT_OF_MEM;
1050 goto err;
1051 }
1052 name->type = GEN_URI;
1053 break;
1054 default:
1055 break;
1056 }
1057
1058 *out_name = name;
1059
1060 return 1;
1061
1062 err:
1063 x509_constraints_name_free(name);
1064 if (out_error != NULL)
1065 *out_error = error;
1066
1067 return 0;
1068}
1069
1070int
1071x509_constraints_extract_constraints(X509 *cert,
1072 struct x509_constraints_names *permitted,
1073 struct x509_constraints_names *excluded,
1074 int *error)
1075{
1076 struct x509_constraints_name *vname = NULL;
1077 NAME_CONSTRAINTS *nc = cert->nc;
1078 GENERAL_SUBTREE *subtree;
1079 int i;
1080
1081 if (nc == NULL)
1082 return 1;
1083
1084 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
1085 subtree = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
1086 if (subtree->minimum || subtree->maximum) {
1087 *error = X509_V_ERR_SUBTREE_MINMAX;
1088 return 0;
1089 }
1090 if (!x509_constraints_validate(subtree->base, &vname, error))
1091 return 0;
1092 if (vname->type == 0) {
1093 x509_constraints_name_free(vname);
1094 vname = NULL;
1095 continue;
1096 }
1097 if (!x509_constraints_names_add(permitted, vname)) {
1098 x509_constraints_name_free(vname);
1099 vname = NULL;
1100 *error = X509_V_ERR_OUT_OF_MEM;
1101 return 0;
1102 }
1103 vname = NULL;
1104 }
1105
1106 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
1107 subtree = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
1108 if (subtree->minimum || subtree->maximum) {
1109 *error = X509_V_ERR_SUBTREE_MINMAX;
1110 return 0;
1111 }
1112 if (!x509_constraints_validate(subtree->base, &vname, error))
1113 return 0;
1114 if (vname->type == 0) {
1115 x509_constraints_name_free(vname);
1116 vname = NULL;
1117 continue;
1118 }
1119 if (!x509_constraints_names_add(excluded, vname)) {
1120 x509_constraints_name_free(vname);
1121 vname = NULL;
1122 *error = X509_V_ERR_OUT_OF_MEM;
1123 return 0;
1124 }
1125 vname = NULL;
1126 }
1127
1128 return 1;
1129}
1130
1131/*
1132 * Match a validated name in "name" against a validated constraint in
1133 * "constraint" return 1 if then name matches, 0 otherwise.
1134 */
1135int
1136x509_constraints_match(struct x509_constraints_name *name,
1137 struct x509_constraints_name *constraint)
1138{
1139 if (name->type != constraint->type)
1140 return 0;
1141 if (name->type == GEN_DNS)
1142 return x509_constraints_sandns(name->name, strlen(name->name),
1143 constraint->name, strlen(constraint->name));
1144 if (name->type == GEN_URI)
1145 return x509_constraints_domain(name->name, strlen(name->name),
1146 constraint->name, strlen(constraint->name));
1147 if (name->type == GEN_IPADD) {
1148 size_t nlen = name->af == AF_INET ? 4 : 16;
1149 size_t clen = name->af == AF_INET ? 8 : 32;
1150 if (name->af != AF_INET && name->af != AF_INET6)
1151 return 0;
1152 if (constraint->af != AF_INET && constraint->af != AF_INET6)
1153 return 0;
1154 if (name->af != constraint->af)
1155 return 0;
1156 return x509_constraints_ipaddr(name->address, nlen,
1157 constraint->address, clen);
1158 }
1159 if (name->type == GEN_EMAIL) {
1160 if (constraint->local) {
1161 /* mailbox local and domain parts must exactly match */
1162 return (strcmp(name->local, constraint->local) == 0 &&
1163 strcmp(name->name, constraint->name) == 0);
1164 }
1165 /* otherwise match the constraint to the domain part */
1166 return x509_constraints_domain(name->name, strlen(name->name),
1167 constraint->name, strlen(constraint->name));
1168 }
1169 if (name->type == GEN_DIRNAME)
1170 return x509_constraints_dirname(name->der, name->der_len,
1171 constraint->der, constraint->der_len);
1172 return 0;
1173}
1174
1175/*
1176 * Make sure every name in names does not match any excluded
1177 * constraints, and does match at least one permitted constraint if
1178 * any are present. Returns 1 if ok, 0, and sets error if not.
1179 */
1180int
1181x509_constraints_check(struct x509_constraints_names *names,
1182 struct x509_constraints_names *permitted,
1183 struct x509_constraints_names *excluded, int *error)
1184{
1185 size_t i, j;
1186
1187 for (i = 0; i < names->names_count; i++) {
1188 int permitted_seen = 0;
1189 int permitted_matched = 0;
1190
1191 for (j = 0; j < excluded->names_count; j++) {
1192 if (x509_constraints_match(names->names[i],
1193 excluded->names[j])) {
1194 *error = X509_V_ERR_EXCLUDED_VIOLATION;
1195 return 0;
1196 }
1197 }
1198 for (j = 0; j < permitted->names_count; j++) {
1199 if (permitted->names[j]->type == names->names[i]->type)
1200 permitted_seen++;
1201 if (x509_constraints_match(names->names[i],
1202 permitted->names[j])) {
1203 permitted_matched++;
1204 break;
1205 }
1206 }
1207 if (permitted_seen && !permitted_matched) {
1208 *error = X509_V_ERR_PERMITTED_VIOLATION;
1209 return 0;
1210 }
1211 }
1212 return 1;
1213}
1214
1215/*
1216 * Walk a validated chain of X509 certs, starting at the leaf, and
1217 * validate the name constraints in the chain. Intended for use with
1218 * the legacy X509 validation code in x509_vfy.c
1219 *
1220 * returns 1 if the constraints are ok, 0 otherwise, setting error and
1221 * depth
1222 */
1223int
1224x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth)
1225{
1226 int chain_length, verify_err = X509_V_ERR_UNSPECIFIED, i = 0;
1227 struct x509_constraints_names *names = NULL;
1228 struct x509_constraints_names *excluded = NULL;
1229 struct x509_constraints_names *permitted = NULL;
1230 size_t constraints_count = 0;
1231 X509 *cert;
1232
1233 if (chain == NULL || (chain_length = sk_X509_num(chain)) == 0)
1234 goto err;
1235 if (chain_length == 1)
1236 return 1;
1237 if ((names = x509_constraints_names_new(
1238 X509_VERIFY_MAX_CHAIN_NAMES)) == NULL) {
1239 verify_err = X509_V_ERR_OUT_OF_MEM;
1240 goto err;
1241 }
1242
1243 if ((cert = sk_X509_value(chain, 0)) == NULL)
1244 goto err;
1245 if (!x509_constraints_extract_names(names, cert, 1, &verify_err))
1246 goto err;
1247 for (i = 1; i < chain_length; i++) {
1248 if ((cert = sk_X509_value(chain, i)) == NULL)
1249 goto err;
1250 if (cert->nc != NULL) {
1251 if ((permitted = x509_constraints_names_new(
1252 X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) {
1253 verify_err = X509_V_ERR_OUT_OF_MEM;
1254 goto err;
1255 }
1256 if ((excluded = x509_constraints_names_new(
1257 X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) {
1258 verify_err = X509_V_ERR_OUT_OF_MEM;
1259 goto err;
1260 }
1261 if (!x509_constraints_extract_constraints(cert,
1262 permitted, excluded, &verify_err))
1263 goto err;
1264 constraints_count += permitted->names_count;
1265 constraints_count += excluded->names_count;
1266 if (constraints_count >
1267 X509_VERIFY_MAX_CHAIN_CONSTRAINTS) {
1268 verify_err = X509_V_ERR_OUT_OF_MEM;
1269 goto err;
1270 }
1271 if (!x509_constraints_check(names, permitted, excluded,
1272 &verify_err))
1273 goto err;
1274 x509_constraints_names_free(excluded);
1275 excluded = NULL;
1276 x509_constraints_names_free(permitted);
1277 permitted = NULL;
1278 }
1279 if (!x509_constraints_extract_names(names, cert, 0,
1280 &verify_err))
1281 goto err;
1282 }
1283
1284 x509_constraints_names_free(names);
1285 return 1;
1286
1287 err:
1288 *error = verify_err;
1289 *depth = i;
1290 x509_constraints_names_free(excluded);
1291 x509_constraints_names_free(permitted);
1292 x509_constraints_names_free(names);
1293 return 0;
1294}
diff --git a/src/lib/libcrypto/x509/x509_cpols.c b/src/lib/libcrypto/x509/x509_cpols.c
deleted file mode 100644
index 6bae2a0482..0000000000
--- a/src/lib/libcrypto/x509/x509_cpols.c
+++ /dev/null
@@ -1,773 +0,0 @@
1/* $OpenBSD: x509_cpols.c,v 1.15 2025/03/06 07:20:01 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
64#include <openssl/conf.h>
65#include <openssl/err.h>
66#include <openssl/x509v3.h>
67
68#include "x509_local.h"
69
70/* Certificate policies extension support: this one is a bit complex... */
71
72static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
73 BIO *out, int indent);
74static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
75 X509V3_CTX *ctx, char *value);
76static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
77 int indent);
78static void print_notice(BIO *out, USERNOTICE *notice, int indent);
79static POLICYINFO *policy_section(X509V3_CTX *ctx,
80 STACK_OF(CONF_VALUE) *polstrs, int ia5org);
81static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
82 STACK_OF(CONF_VALUE) *unot, int ia5org);
83static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
84
85static const X509V3_EXT_METHOD x509v3_ext_certificate_policies = {
86 .ext_nid = NID_certificate_policies,
87 .ext_flags = 0,
88 .it = &CERTIFICATEPOLICIES_it,
89 .ext_new = NULL,
90 .ext_free = NULL,
91 .d2i = NULL,
92 .i2d = NULL,
93 .i2s = NULL,
94 .s2i = NULL,
95 .i2v = NULL,
96 .v2i = NULL,
97 .i2r = (X509V3_EXT_I2R)i2r_certpol,
98 .r2i = (X509V3_EXT_R2I)r2i_certpol,
99 .usr_data = NULL,
100};
101
102const X509V3_EXT_METHOD *
103x509v3_ext_method_certificate_policies(void)
104{
105 return &x509v3_ext_certificate_policies;
106}
107
108static const ASN1_TEMPLATE CERTIFICATEPOLICIES_item_tt = {
109 .flags = ASN1_TFLG_SEQUENCE_OF,
110 .tag = 0,
111 .offset = 0,
112 .field_name = "CERTIFICATEPOLICIES",
113 .item = &POLICYINFO_it,
114};
115
116const ASN1_ITEM CERTIFICATEPOLICIES_it = {
117 .itype = ASN1_ITYPE_PRIMITIVE,
118 .utype = -1,
119 .templates = &CERTIFICATEPOLICIES_item_tt,
120 .tcount = 0,
121 .funcs = NULL,
122 .size = 0,
123 .sname = "CERTIFICATEPOLICIES",
124};
125LCRYPTO_ALIAS(CERTIFICATEPOLICIES_it);
126
127
128CERTIFICATEPOLICIES *
129d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len)
130{
131 return (CERTIFICATEPOLICIES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
132 &CERTIFICATEPOLICIES_it);
133}
134LCRYPTO_ALIAS(d2i_CERTIFICATEPOLICIES);
135
136int
137i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out)
138{
139 return ASN1_item_i2d((ASN1_VALUE *)a, out, &CERTIFICATEPOLICIES_it);
140}
141LCRYPTO_ALIAS(i2d_CERTIFICATEPOLICIES);
142
143CERTIFICATEPOLICIES *
144CERTIFICATEPOLICIES_new(void)
145{
146 return (CERTIFICATEPOLICIES *)ASN1_item_new(&CERTIFICATEPOLICIES_it);
147}
148LCRYPTO_ALIAS(CERTIFICATEPOLICIES_new);
149
150void
151CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a)
152{
153 ASN1_item_free((ASN1_VALUE *)a, &CERTIFICATEPOLICIES_it);
154}
155LCRYPTO_ALIAS(CERTIFICATEPOLICIES_free);
156
157static const ASN1_TEMPLATE POLICYINFO_seq_tt[] = {
158 {
159 .flags = 0,
160 .tag = 0,
161 .offset = offsetof(POLICYINFO, policyid),
162 .field_name = "policyid",
163 .item = &ASN1_OBJECT_it,
164 },
165 {
166 .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
167 .tag = 0,
168 .offset = offsetof(POLICYINFO, qualifiers),
169 .field_name = "qualifiers",
170 .item = &POLICYQUALINFO_it,
171 },
172};
173
174const ASN1_ITEM POLICYINFO_it = {
175 .itype = ASN1_ITYPE_SEQUENCE,
176 .utype = V_ASN1_SEQUENCE,
177 .templates = POLICYINFO_seq_tt,
178 .tcount = sizeof(POLICYINFO_seq_tt) / sizeof(ASN1_TEMPLATE),
179 .funcs = NULL,
180 .size = sizeof(POLICYINFO),
181 .sname = "POLICYINFO",
182};
183LCRYPTO_ALIAS(POLICYINFO_it);
184
185
186POLICYINFO *
187d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len)
188{
189 return (POLICYINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
190 &POLICYINFO_it);
191}
192LCRYPTO_ALIAS(d2i_POLICYINFO);
193
194int
195i2d_POLICYINFO(POLICYINFO *a, unsigned char **out)
196{
197 return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYINFO_it);
198}
199LCRYPTO_ALIAS(i2d_POLICYINFO);
200
201POLICYINFO *
202POLICYINFO_new(void)
203{
204 return (POLICYINFO *)ASN1_item_new(&POLICYINFO_it);
205}
206LCRYPTO_ALIAS(POLICYINFO_new);
207
208void
209POLICYINFO_free(POLICYINFO *a)
210{
211 ASN1_item_free((ASN1_VALUE *)a, &POLICYINFO_it);
212}
213LCRYPTO_ALIAS(POLICYINFO_free);
214
215static const ASN1_TEMPLATE policydefault_tt = {
216 .flags = 0,
217 .tag = 0,
218 .offset = offsetof(POLICYQUALINFO, d.other),
219 .field_name = "d.other",
220 .item = &ASN1_ANY_it,
221};
222
223static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl[] = {
224 {
225 .value = NID_id_qt_cps,
226 .tt = {
227 .flags = 0,
228 .tag = 0,
229 .offset = offsetof(POLICYQUALINFO, d.cpsuri),
230 .field_name = "d.cpsuri",
231 .item = &ASN1_IA5STRING_it,
232 },
233 },
234 {
235 .value = NID_id_qt_unotice,
236 .tt = {
237 .flags = 0,
238 .tag = 0,
239 .offset = offsetof(POLICYQUALINFO, d.usernotice),
240 .field_name = "d.usernotice",
241 .item = &USERNOTICE_it,
242 },
243 },
244};
245
246static const ASN1_ADB POLICYQUALINFO_adb = {
247 .flags = 0,
248 .offset = offsetof(POLICYQUALINFO, pqualid),
249 .tbl = POLICYQUALINFO_adbtbl,
250 .tblcount = sizeof(POLICYQUALINFO_adbtbl) / sizeof(ASN1_ADB_TABLE),
251 .default_tt = &policydefault_tt,
252 .null_tt = NULL,
253};
254
255static const ASN1_TEMPLATE POLICYQUALINFO_seq_tt[] = {
256 {
257 .flags = 0,
258 .tag = 0,
259 .offset = offsetof(POLICYQUALINFO, pqualid),
260 .field_name = "pqualid",
261 .item = &ASN1_OBJECT_it,
262 },
263 {
264 .flags = ASN1_TFLG_ADB_OID,
265 .tag = -1,
266 .offset = 0,
267 .field_name = "POLICYQUALINFO",
268 .item = (const ASN1_ITEM *)&POLICYQUALINFO_adb,
269 },
270};
271
272const ASN1_ITEM POLICYQUALINFO_it = {
273 .itype = ASN1_ITYPE_SEQUENCE,
274 .utype = V_ASN1_SEQUENCE,
275 .templates = POLICYQUALINFO_seq_tt,
276 .tcount = sizeof(POLICYQUALINFO_seq_tt) / sizeof(ASN1_TEMPLATE),
277 .funcs = NULL,
278 .size = sizeof(POLICYQUALINFO),
279 .sname = "POLICYQUALINFO",
280};
281LCRYPTO_ALIAS(POLICYQUALINFO_it);
282
283
284POLICYQUALINFO *
285d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len)
286{
287 return (POLICYQUALINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
288 &POLICYQUALINFO_it);
289}
290LCRYPTO_ALIAS(d2i_POLICYQUALINFO);
291
292int
293i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out)
294{
295 return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYQUALINFO_it);
296}
297LCRYPTO_ALIAS(i2d_POLICYQUALINFO);
298
299POLICYQUALINFO *
300POLICYQUALINFO_new(void)
301{
302 return (POLICYQUALINFO *)ASN1_item_new(&POLICYQUALINFO_it);
303}
304LCRYPTO_ALIAS(POLICYQUALINFO_new);
305
306void
307POLICYQUALINFO_free(POLICYQUALINFO *a)
308{
309 ASN1_item_free((ASN1_VALUE *)a, &POLICYQUALINFO_it);
310}
311LCRYPTO_ALIAS(POLICYQUALINFO_free);
312
313static const ASN1_TEMPLATE USERNOTICE_seq_tt[] = {
314 {
315 .flags = ASN1_TFLG_OPTIONAL,
316 .tag = 0,
317 .offset = offsetof(USERNOTICE, noticeref),
318 .field_name = "noticeref",
319 .item = &NOTICEREF_it,
320 },
321 {
322 .flags = ASN1_TFLG_OPTIONAL,
323 .tag = 0,
324 .offset = offsetof(USERNOTICE, exptext),
325 .field_name = "exptext",
326 .item = &DISPLAYTEXT_it,
327 },
328};
329
330const ASN1_ITEM USERNOTICE_it = {
331 .itype = ASN1_ITYPE_SEQUENCE,
332 .utype = V_ASN1_SEQUENCE,
333 .templates = USERNOTICE_seq_tt,
334 .tcount = sizeof(USERNOTICE_seq_tt) / sizeof(ASN1_TEMPLATE),
335 .funcs = NULL,
336 .size = sizeof(USERNOTICE),
337 .sname = "USERNOTICE",
338};
339LCRYPTO_ALIAS(USERNOTICE_it);
340
341
342USERNOTICE *
343d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len)
344{
345 return (USERNOTICE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
346 &USERNOTICE_it);
347}
348LCRYPTO_ALIAS(d2i_USERNOTICE);
349
350int
351i2d_USERNOTICE(USERNOTICE *a, unsigned char **out)
352{
353 return ASN1_item_i2d((ASN1_VALUE *)a, out, &USERNOTICE_it);
354}
355LCRYPTO_ALIAS(i2d_USERNOTICE);
356
357USERNOTICE *
358USERNOTICE_new(void)
359{
360 return (USERNOTICE *)ASN1_item_new(&USERNOTICE_it);
361}
362LCRYPTO_ALIAS(USERNOTICE_new);
363
364void
365USERNOTICE_free(USERNOTICE *a)
366{
367 ASN1_item_free((ASN1_VALUE *)a, &USERNOTICE_it);
368}
369LCRYPTO_ALIAS(USERNOTICE_free);
370
371static const ASN1_TEMPLATE NOTICEREF_seq_tt[] = {
372 {
373 .flags = 0,
374 .tag = 0,
375 .offset = offsetof(NOTICEREF, organization),
376 .field_name = "organization",
377 .item = &DISPLAYTEXT_it,
378 },
379 {
380 .flags = ASN1_TFLG_SEQUENCE_OF,
381 .tag = 0,
382 .offset = offsetof(NOTICEREF, noticenos),
383 .field_name = "noticenos",
384 .item = &ASN1_INTEGER_it,
385 },
386};
387
388const ASN1_ITEM NOTICEREF_it = {
389 .itype = ASN1_ITYPE_SEQUENCE,
390 .utype = V_ASN1_SEQUENCE,
391 .templates = NOTICEREF_seq_tt,
392 .tcount = sizeof(NOTICEREF_seq_tt) / sizeof(ASN1_TEMPLATE),
393 .funcs = NULL,
394 .size = sizeof(NOTICEREF),
395 .sname = "NOTICEREF",
396};
397LCRYPTO_ALIAS(NOTICEREF_it);
398
399
400NOTICEREF *
401d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len)
402{
403 return (NOTICEREF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
404 &NOTICEREF_it);
405}
406LCRYPTO_ALIAS(d2i_NOTICEREF);
407
408int
409i2d_NOTICEREF(NOTICEREF *a, unsigned char **out)
410{
411 return ASN1_item_i2d((ASN1_VALUE *)a, out, &NOTICEREF_it);
412}
413LCRYPTO_ALIAS(i2d_NOTICEREF);
414
415NOTICEREF *
416NOTICEREF_new(void)
417{
418 return (NOTICEREF *)ASN1_item_new(&NOTICEREF_it);
419}
420LCRYPTO_ALIAS(NOTICEREF_new);
421
422void
423NOTICEREF_free(NOTICEREF *a)
424{
425 ASN1_item_free((ASN1_VALUE *)a, &NOTICEREF_it);
426}
427LCRYPTO_ALIAS(NOTICEREF_free);
428
429static STACK_OF(POLICYINFO) *
430r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value)
431{
432 STACK_OF(POLICYINFO) *pols = NULL;
433 char *pstr;
434 POLICYINFO *pol;
435 ASN1_OBJECT *pobj;
436 STACK_OF(CONF_VALUE) *vals;
437 CONF_VALUE *cnf;
438 int i, ia5org;
439
440 pols = sk_POLICYINFO_new_null();
441 if (pols == NULL) {
442 X509V3error(ERR_R_MALLOC_FAILURE);
443 return NULL;
444 }
445 vals = X509V3_parse_list(value);
446 if (vals == NULL) {
447 X509V3error(ERR_R_X509V3_LIB);
448 goto err;
449 }
450 ia5org = 0;
451 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
452 cnf = sk_CONF_VALUE_value(vals, i);
453 if (cnf->value || !cnf->name) {
454 X509V3error(X509V3_R_INVALID_POLICY_IDENTIFIER);
455 X509V3_conf_err(cnf);
456 goto err;
457 }
458 pstr = cnf->name;
459 if (!strcmp(pstr, "ia5org")) {
460 ia5org = 1;
461 continue;
462 } else if (*pstr == '@') {
463 STACK_OF(CONF_VALUE) *polsect;
464 polsect = X509V3_get0_section(ctx, pstr + 1);
465 if (!polsect) {
466 X509V3error(X509V3_R_INVALID_SECTION);
467 X509V3_conf_err(cnf);
468 goto err;
469 }
470 pol = policy_section(ctx, polsect, ia5org);
471 if (!pol)
472 goto err;
473 } else {
474 if (!(pobj = OBJ_txt2obj(cnf->name, 0))) {
475 X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
476 X509V3_conf_err(cnf);
477 goto err;
478 }
479 pol = POLICYINFO_new();
480 pol->policyid = pobj;
481 }
482 if (!sk_POLICYINFO_push(pols, pol)){
483 POLICYINFO_free(pol);
484 X509V3error(ERR_R_MALLOC_FAILURE);
485 goto err;
486 }
487 }
488 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
489 return pols;
490
491err:
492 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
493 sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
494 return NULL;
495}
496
497static POLICYINFO *
498policy_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *polstrs, int ia5org)
499{
500 int i;
501 CONF_VALUE *cnf;
502 POLICYINFO *pol;
503 POLICYQUALINFO *nqual = NULL;
504
505 if ((pol = POLICYINFO_new()) == NULL)
506 goto merr;
507 for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
508 cnf = sk_CONF_VALUE_value(polstrs, i);
509 if (strcmp(cnf->name, "policyIdentifier") == 0) {
510 ASN1_OBJECT *pobj;
511
512 if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) {
513 X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
514 X509V3_conf_err(cnf);
515 goto err;
516 }
517 pol->policyid = pobj;
518 } else if (name_cmp(cnf->name, "CPS") == 0) {
519 if ((nqual = POLICYQUALINFO_new()) == NULL)
520 goto merr;
521 nqual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
522 nqual->d.cpsuri = ASN1_IA5STRING_new();
523 if (nqual->d.cpsuri == NULL)
524 goto merr;
525 if (ASN1_STRING_set(nqual->d.cpsuri, cnf->value,
526 strlen(cnf->value)) == 0)
527 goto merr;
528
529 if (pol->qualifiers == NULL) {
530 pol->qualifiers = sk_POLICYQUALINFO_new_null();
531 if (pol->qualifiers == NULL)
532 goto merr;
533 }
534 if (sk_POLICYQUALINFO_push(pol->qualifiers, nqual) == 0)
535 goto merr;
536 nqual = NULL;
537 } else if (name_cmp(cnf->name, "userNotice") == 0) {
538 STACK_OF(CONF_VALUE) *unot;
539 POLICYQUALINFO *qual;
540
541 if (*cnf->value != '@') {
542 X509V3error(X509V3_R_EXPECTED_A_SECTION_NAME);
543 X509V3_conf_err(cnf);
544 goto err;
545 }
546 unot = X509V3_get0_section(ctx, cnf->value + 1);
547 if (unot == NULL) {
548 X509V3error(X509V3_R_INVALID_SECTION);
549 X509V3_conf_err(cnf);
550 goto err;
551 }
552 qual = notice_section(ctx, unot, ia5org);
553 if (qual == NULL)
554 goto err;
555
556 if (pol->qualifiers == NULL) {
557 pol->qualifiers = sk_POLICYQUALINFO_new_null();
558 if (pol->qualifiers == NULL)
559 goto merr;
560 }
561 if (sk_POLICYQUALINFO_push(pol->qualifiers, qual) == 0)
562 goto merr;
563 } else {
564 X509V3error(X509V3_R_INVALID_OPTION);
565 X509V3_conf_err(cnf);
566 goto err;
567 }
568 }
569 if (pol->policyid == NULL) {
570 X509V3error(X509V3_R_NO_POLICY_IDENTIFIER);
571 goto err;
572 }
573
574 return pol;
575
576merr:
577 X509V3error(ERR_R_MALLOC_FAILURE);
578
579err:
580 POLICYQUALINFO_free(nqual);
581 POLICYINFO_free(pol);
582 return NULL;
583}
584
585static POLICYQUALINFO *
586notice_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *unot, int ia5org)
587{
588 int i, ret;
589 CONF_VALUE *cnf;
590 USERNOTICE *not;
591 POLICYQUALINFO *qual;
592
593 if (!(qual = POLICYQUALINFO_new()))
594 goto merr;
595 qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
596 if (!(not = USERNOTICE_new()))
597 goto merr;
598 qual->d.usernotice = not;
599 for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
600 cnf = sk_CONF_VALUE_value(unot, i);
601 if (!strcmp(cnf->name, "explicitText")) {
602 if (not->exptext == NULL) {
603 not->exptext = ASN1_UTF8STRING_new();
604 if (not->exptext == NULL)
605 goto merr;
606 }
607 if (!ASN1_STRING_set(not->exptext, cnf->value,
608 strlen(cnf->value)))
609 goto merr;
610 } else if (!strcmp(cnf->name, "organization")) {
611 NOTICEREF *nref;
612 if (!not->noticeref) {
613 if (!(nref = NOTICEREF_new()))
614 goto merr;
615 not->noticeref = nref;
616 } else
617 nref = not->noticeref;
618 if (ia5org)
619 nref->organization->type = V_ASN1_IA5STRING;
620 else
621 nref->organization->type = V_ASN1_VISIBLESTRING;
622 if (!ASN1_STRING_set(nref->organization, cnf->value,
623 strlen(cnf->value)))
624 goto merr;
625 } else if (!strcmp(cnf->name, "noticeNumbers")) {
626 NOTICEREF *nref;
627 STACK_OF(CONF_VALUE) *nos;
628 if (!not->noticeref) {
629 if (!(nref = NOTICEREF_new()))
630 goto merr;
631 not->noticeref = nref;
632 } else
633 nref = not->noticeref;
634 nos = X509V3_parse_list(cnf->value);
635 if (!nos || !sk_CONF_VALUE_num(nos)) {
636 X509V3error(X509V3_R_INVALID_NUMBERS);
637 X509V3_conf_err(cnf);
638 if (nos != NULL)
639 sk_CONF_VALUE_pop_free(nos,
640 X509V3_conf_free);
641 goto err;
642 }
643 ret = nref_nos(nref->noticenos, nos);
644 sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
645 if (!ret)
646 goto err;
647 } else {
648 X509V3error(X509V3_R_INVALID_OPTION);
649 X509V3_conf_err(cnf);
650 goto err;
651 }
652 }
653
654 if (not->noticeref &&
655 (!not->noticeref->noticenos || !not->noticeref->organization)) {
656 X509V3error(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
657 goto err;
658 }
659
660 return qual;
661
662merr:
663 X509V3error(ERR_R_MALLOC_FAILURE);
664
665err:
666 POLICYQUALINFO_free(qual);
667 return NULL;
668}
669
670static int
671nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
672{
673 CONF_VALUE *cnf;
674 ASN1_INTEGER *aint;
675 int i;
676
677 for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
678 cnf = sk_CONF_VALUE_value(nos, i);
679 if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
680 X509V3error(X509V3_R_INVALID_NUMBER);
681 goto err;
682 }
683 if (!sk_ASN1_INTEGER_push(nnums, aint))
684 goto merr;
685 }
686 return 1;
687
688merr:
689 X509V3error(ERR_R_MALLOC_FAILURE);
690
691err:
692 sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
693 return 0;
694}
695
696static int
697i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out,
698 int indent)
699{
700 int i;
701 POLICYINFO *pinfo;
702
703 /* First print out the policy OIDs */
704 for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
705 pinfo = sk_POLICYINFO_value(pol, i);
706 BIO_printf(out, "%*sPolicy: ", indent, "");
707 i2a_ASN1_OBJECT(out, pinfo->policyid);
708 BIO_puts(out, "\n");
709 if (pinfo->qualifiers)
710 print_qualifiers(out, pinfo->qualifiers, indent + 2);
711 }
712 return 1;
713}
714
715static void
716print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent)
717{
718 POLICYQUALINFO *qualinfo;
719 int i;
720
721 for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
722 qualinfo = sk_POLICYQUALINFO_value(quals, i);
723 switch (OBJ_obj2nid(qualinfo->pqualid)) {
724 case NID_id_qt_cps:
725 BIO_printf(out, "%*sCPS: %.*s\n", indent, "",
726 qualinfo->d.cpsuri->length,
727 qualinfo->d.cpsuri->data);
728 break;
729
730 case NID_id_qt_unotice:
731 BIO_printf(out, "%*sUser Notice:\n", indent, "");
732 print_notice(out, qualinfo->d.usernotice, indent + 2);
733 break;
734
735 default:
736 BIO_printf(out, "%*sUnknown Qualifier: ",
737 indent + 2, "");
738
739 i2a_ASN1_OBJECT(out, qualinfo->pqualid);
740 BIO_puts(out, "\n");
741 break;
742 }
743 }
744}
745
746static void
747print_notice(BIO *out, USERNOTICE *notice, int indent)
748{
749 int i;
750
751 if (notice->noticeref) {
752 NOTICEREF *ref;
753 ref = notice->noticeref;
754 BIO_printf(out, "%*sOrganization: %.*s\n", indent, "",
755 ref->organization->length, ref->organization->data);
756 BIO_printf(out, "%*sNumber%s: ", indent, "",
757 sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
758 for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
759 ASN1_INTEGER *num;
760 char *tmp;
761 num = sk_ASN1_INTEGER_value(ref->noticenos, i);
762 if (i)
763 BIO_puts(out, ", ");
764 tmp = i2s_ASN1_INTEGER(NULL, num);
765 BIO_puts(out, tmp);
766 free(tmp);
767 }
768 BIO_puts(out, "\n");
769 }
770 if (notice->exptext)
771 BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "",
772 notice->exptext->length, notice->exptext->data);
773}
diff --git a/src/lib/libcrypto/x509/x509_crld.c b/src/lib/libcrypto/x509/x509_crld.c
deleted file mode 100644
index 81f2010df5..0000000000
--- a/src/lib/libcrypto/x509/x509_crld.c
+++ /dev/null
@@ -1,852 +0,0 @@
1/* $OpenBSD: x509_crld.c,v 1.9 2025/03/06 07:20:01 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2008 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
64#include <openssl/conf.h>
65#include <openssl/err.h>
66#include <openssl/x509v3.h>
67
68#include "x509_local.h"
69
70static void *v2i_crld(const X509V3_EXT_METHOD *method,
71 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
72static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
73 int indent);
74
75static const X509V3_EXT_METHOD x509v3_ext_crl_distribution_points = {
76 .ext_nid = NID_crl_distribution_points,
77 .ext_flags = 0,
78 .it = &CRL_DIST_POINTS_it,
79 .ext_new = NULL,
80 .ext_free = NULL,
81 .d2i = NULL,
82 .i2d = NULL,
83 .i2s = NULL,
84 .s2i = NULL,
85 .i2v = NULL,
86 .v2i = v2i_crld,
87 .i2r = i2r_crldp,
88 .r2i = NULL,
89 .usr_data = NULL,
90};
91
92const X509V3_EXT_METHOD *
93x509v3_ext_method_crl_distribution_points(void)
94{
95 return &x509v3_ext_crl_distribution_points;
96}
97
98static const X509V3_EXT_METHOD x509v3_ext_freshest_crl = {
99 .ext_nid = NID_freshest_crl,
100 .ext_flags = 0,
101 .it = &CRL_DIST_POINTS_it,
102 .ext_new = NULL,
103 .ext_free = NULL,
104 .d2i = NULL,
105 .i2d = NULL,
106 .i2s = NULL,
107 .s2i = NULL,
108 .i2v = NULL,
109 .v2i = v2i_crld,
110 .i2r = i2r_crldp,
111 .r2i = NULL,
112 .usr_data = NULL,
113};
114
115const X509V3_EXT_METHOD *
116x509v3_ext_method_freshest_crl(void)
117{
118 return &x509v3_ext_freshest_crl;
119}
120
121static STACK_OF(GENERAL_NAME) *
122gnames_from_sectname(X509V3_CTX *ctx, char *sect)
123{
124 STACK_OF(CONF_VALUE) *gnsect;
125 STACK_OF(GENERAL_NAME) *gens;
126
127 if (*sect == '@')
128 gnsect = X509V3_get0_section(ctx, sect + 1);
129 else
130 gnsect = X509V3_parse_list(sect);
131 if (!gnsect) {
132 X509V3error(X509V3_R_SECTION_NOT_FOUND);
133 return NULL;
134 }
135 gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
136 if (*sect != '@')
137 sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
138 return gens;
139}
140
141static int
142set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, CONF_VALUE *cnf)
143{
144 STACK_OF(GENERAL_NAME) *fnm = NULL;
145 STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
146
147 if (!strncmp(cnf->name, "fullname", 9)) {
148 fnm = gnames_from_sectname(ctx, cnf->value);
149 if (!fnm)
150 goto err;
151 } else if (!strcmp(cnf->name, "relativename")) {
152 int ret;
153 STACK_OF(CONF_VALUE) *dnsect;
154 X509_NAME *nm;
155 nm = X509_NAME_new();
156 if (!nm)
157 return -1;
158 dnsect = X509V3_get0_section(ctx, cnf->value);
159 if (!dnsect) {
160 X509V3error(X509V3_R_SECTION_NOT_FOUND);
161 X509_NAME_free(nm);
162 return -1;
163 }
164 ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
165 rnm = nm->entries;
166 nm->entries = NULL;
167 X509_NAME_free(nm);
168 if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
169 goto err;
170 /* Since its a name fragment can't have more than one
171 * RDNSequence
172 */
173 if (sk_X509_NAME_ENTRY_value(rnm,
174 sk_X509_NAME_ENTRY_num(rnm) - 1)->set) {
175 X509V3error(X509V3_R_INVALID_MULTIPLE_RDNS);
176 goto err;
177 }
178 } else
179 return 0;
180
181 if (*pdp) {
182 X509V3error(X509V3_R_DISTPOINT_ALREADY_SET);
183 goto err;
184 }
185
186 *pdp = DIST_POINT_NAME_new();
187 if (!*pdp)
188 goto err;
189 if (fnm) {
190 (*pdp)->type = 0;
191 (*pdp)->name.fullname = fnm;
192 } else {
193 (*pdp)->type = 1;
194 (*pdp)->name.relativename = rnm;
195 }
196
197 return 1;
198
199err:
200 sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
201 sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
202 return -1;
203}
204
205static const BIT_STRING_BITNAME reason_flags[] = {
206 {0, "Unused", "unused"},
207 {1, "Key Compromise", "keyCompromise"},
208 {2, "CA Compromise", "CACompromise"},
209 {3, "Affiliation Changed", "affiliationChanged"},
210 {4, "Superseded", "superseded"},
211 {5, "Cessation Of Operation", "cessationOfOperation"},
212 {6, "Certificate Hold", "certificateHold"},
213 {7, "Privilege Withdrawn", "privilegeWithdrawn"},
214 {8, "AA Compromise", "AACompromise"},
215 {-1, NULL, NULL}
216};
217
218static int
219set_reasons(ASN1_BIT_STRING **preas, char *value)
220{
221 STACK_OF(CONF_VALUE) *rsk = NULL;
222 const BIT_STRING_BITNAME *pbn;
223 const char *bnam;
224 int i, ret = 0;
225
226 if (*preas != NULL)
227 return 0;
228 rsk = X509V3_parse_list(value);
229 if (rsk == NULL)
230 return 0;
231 for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) {
232 bnam = sk_CONF_VALUE_value(rsk, i)->name;
233 if (!*preas) {
234 *preas = ASN1_BIT_STRING_new();
235 if (!*preas)
236 goto err;
237 }
238 for (pbn = reason_flags; pbn->lname; pbn++) {
239 if (!strcmp(pbn->sname, bnam)) {
240 if (!ASN1_BIT_STRING_set_bit(*preas,
241 pbn->bitnum, 1))
242 goto err;
243 break;
244 }
245 }
246 if (!pbn->lname)
247 goto err;
248 }
249 ret = 1;
250
251err:
252 sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
253 return ret;
254}
255
256static int
257print_reasons(BIO *out, const char *rname, ASN1_BIT_STRING *rflags, int indent)
258{
259 int first = 1;
260 const BIT_STRING_BITNAME *pbn;
261
262 BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
263 for (pbn = reason_flags; pbn->lname; pbn++) {
264 if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) {
265 if (first)
266 first = 0;
267 else
268 BIO_puts(out, ", ");
269 BIO_puts(out, pbn->lname);
270 }
271 }
272 if (first)
273 BIO_puts(out, "<EMPTY>\n");
274 else
275 BIO_puts(out, "\n");
276 return 1;
277}
278
279static DIST_POINT *
280crldp_from_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
281{
282 int i;
283 CONF_VALUE *cnf;
284 DIST_POINT *point = NULL;
285
286 point = DIST_POINT_new();
287 if (!point)
288 goto err;
289 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
290 int ret;
291 cnf = sk_CONF_VALUE_value(nval, i);
292 ret = set_dist_point_name(&point->distpoint, ctx, cnf);
293 if (ret > 0)
294 continue;
295 if (ret < 0)
296 goto err;
297 if (!strcmp(cnf->name, "reasons")) {
298 if (!set_reasons(&point->reasons, cnf->value))
299 goto err;
300 }
301 else if (!strcmp(cnf->name, "CRLissuer")) {
302 point->CRLissuer =
303 gnames_from_sectname(ctx, cnf->value);
304 if (!point->CRLissuer)
305 goto err;
306 }
307 }
308
309 return point;
310
311err:
312 DIST_POINT_free(point);
313 return NULL;
314}
315
316static void *
317v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
318 STACK_OF(CONF_VALUE) *nval)
319{
320 STACK_OF(DIST_POINT) *crld = NULL;
321 GENERAL_NAMES *gens = NULL;
322 GENERAL_NAME *gen = NULL;
323 CONF_VALUE *cnf;
324 int i;
325
326 if (!(crld = sk_DIST_POINT_new_null()))
327 goto merr;
328 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
329 DIST_POINT *point;
330 cnf = sk_CONF_VALUE_value(nval, i);
331 if (!cnf->value) {
332 STACK_OF(CONF_VALUE) *dpsect;
333 dpsect = X509V3_get0_section(ctx, cnf->name);
334 if (!dpsect)
335 goto err;
336 point = crldp_from_section(ctx, dpsect);
337 if (!point)
338 goto err;
339 if (!sk_DIST_POINT_push(crld, point)) {
340 DIST_POINT_free(point);
341 goto merr;
342 }
343 } else {
344 if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf)))
345 goto err;
346 if (!(gens = GENERAL_NAMES_new()))
347 goto merr;
348 if (!sk_GENERAL_NAME_push(gens, gen))
349 goto merr;
350 gen = NULL;
351 if (!(point = DIST_POINT_new()))
352 goto merr;
353 if (!sk_DIST_POINT_push(crld, point)) {
354 DIST_POINT_free(point);
355 goto merr;
356 }
357 if (!(point->distpoint = DIST_POINT_NAME_new()))
358 goto merr;
359 point->distpoint->name.fullname = gens;
360 point->distpoint->type = 0;
361 gens = NULL;
362 }
363 }
364 return crld;
365
366merr:
367 X509V3error(ERR_R_MALLOC_FAILURE);
368err:
369 GENERAL_NAME_free(gen);
370 GENERAL_NAMES_free(gens);
371 sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
372 return NULL;
373}
374
375static int
376dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
377{
378 DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
379
380 switch (operation) {
381 case ASN1_OP_NEW_POST:
382 dpn->dpname = NULL;
383 break;
384
385 case ASN1_OP_FREE_POST:
386 if (dpn->dpname)
387 X509_NAME_free(dpn->dpname);
388 break;
389 }
390 return 1;
391}
392
393
394static const ASN1_AUX DIST_POINT_NAME_aux = {
395 .app_data = NULL,
396 .flags = 0,
397 .ref_offset = 0,
398 .ref_lock = 0,
399 .asn1_cb = dpn_cb,
400 .enc_offset = 0,
401};
402static const ASN1_TEMPLATE DIST_POINT_NAME_ch_tt[] = {
403 {
404 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF,
405 .tag = 0,
406 .offset = offsetof(DIST_POINT_NAME, name.fullname),
407 .field_name = "name.fullname",
408 .item = &GENERAL_NAME_it,
409 },
410 {
411 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF,
412 .tag = 1,
413 .offset = offsetof(DIST_POINT_NAME, name.relativename),
414 .field_name = "name.relativename",
415 .item = &X509_NAME_ENTRY_it,
416 },
417};
418
419const ASN1_ITEM DIST_POINT_NAME_it = {
420 .itype = ASN1_ITYPE_CHOICE,
421 .utype = offsetof(DIST_POINT_NAME, type),
422 .templates = DIST_POINT_NAME_ch_tt,
423 .tcount = sizeof(DIST_POINT_NAME_ch_tt) / sizeof(ASN1_TEMPLATE),
424 .funcs = &DIST_POINT_NAME_aux,
425 .size = sizeof(DIST_POINT_NAME),
426 .sname = "DIST_POINT_NAME",
427};
428LCRYPTO_ALIAS(DIST_POINT_NAME_it);
429
430
431
432DIST_POINT_NAME *
433d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, const unsigned char **in, long len)
434{
435 return (DIST_POINT_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
436 &DIST_POINT_NAME_it);
437}
438LCRYPTO_ALIAS(d2i_DIST_POINT_NAME);
439
440int
441i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out)
442{
443 return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_NAME_it);
444}
445LCRYPTO_ALIAS(i2d_DIST_POINT_NAME);
446
447DIST_POINT_NAME *
448DIST_POINT_NAME_new(void)
449{
450 return (DIST_POINT_NAME *)ASN1_item_new(&DIST_POINT_NAME_it);
451}
452LCRYPTO_ALIAS(DIST_POINT_NAME_new);
453
454void
455DIST_POINT_NAME_free(DIST_POINT_NAME *a)
456{
457 ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_NAME_it);
458}
459LCRYPTO_ALIAS(DIST_POINT_NAME_free);
460
461static const ASN1_TEMPLATE DIST_POINT_seq_tt[] = {
462 {
463 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
464 .tag = 0,
465 .offset = offsetof(DIST_POINT, distpoint),
466 .field_name = "distpoint",
467 .item = &DIST_POINT_NAME_it,
468 },
469 {
470 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
471 .tag = 1,
472 .offset = offsetof(DIST_POINT, reasons),
473 .field_name = "reasons",
474 .item = &ASN1_BIT_STRING_it,
475 },
476 {
477 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
478 .tag = 2,
479 .offset = offsetof(DIST_POINT, CRLissuer),
480 .field_name = "CRLissuer",
481 .item = &GENERAL_NAME_it,
482 },
483};
484
485const ASN1_ITEM DIST_POINT_it = {
486 .itype = ASN1_ITYPE_SEQUENCE,
487 .utype = V_ASN1_SEQUENCE,
488 .templates = DIST_POINT_seq_tt,
489 .tcount = sizeof(DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE),
490 .funcs = NULL,
491 .size = sizeof(DIST_POINT),
492 .sname = "DIST_POINT",
493};
494LCRYPTO_ALIAS(DIST_POINT_it);
495
496
497DIST_POINT *
498d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len)
499{
500 return (DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
501 &DIST_POINT_it);
502}
503LCRYPTO_ALIAS(d2i_DIST_POINT);
504
505int
506i2d_DIST_POINT(DIST_POINT *a, unsigned char **out)
507{
508 return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIST_POINT_it);
509}
510LCRYPTO_ALIAS(i2d_DIST_POINT);
511
512DIST_POINT *
513DIST_POINT_new(void)
514{
515 return (DIST_POINT *)ASN1_item_new(&DIST_POINT_it);
516}
517LCRYPTO_ALIAS(DIST_POINT_new);
518
519void
520DIST_POINT_free(DIST_POINT *a)
521{
522 ASN1_item_free((ASN1_VALUE *)a, &DIST_POINT_it);
523}
524LCRYPTO_ALIAS(DIST_POINT_free);
525
526static const ASN1_TEMPLATE CRL_DIST_POINTS_item_tt = {
527 .flags = ASN1_TFLG_SEQUENCE_OF,
528 .tag = 0,
529 .offset = 0,
530 .field_name = "CRLDistributionPoints",
531 .item = &DIST_POINT_it,
532};
533
534const ASN1_ITEM CRL_DIST_POINTS_it = {
535 .itype = ASN1_ITYPE_PRIMITIVE,
536 .utype = -1,
537 .templates = &CRL_DIST_POINTS_item_tt,
538 .tcount = 0,
539 .funcs = NULL,
540 .size = 0,
541 .sname = "CRL_DIST_POINTS",
542};
543LCRYPTO_ALIAS(CRL_DIST_POINTS_it);
544
545
546CRL_DIST_POINTS *
547d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len)
548{
549 return (CRL_DIST_POINTS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
550 &CRL_DIST_POINTS_it);
551}
552LCRYPTO_ALIAS(d2i_CRL_DIST_POINTS);
553
554int
555i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out)
556{
557 return ASN1_item_i2d((ASN1_VALUE *)a, out, &CRL_DIST_POINTS_it);
558}
559LCRYPTO_ALIAS(i2d_CRL_DIST_POINTS);
560
561CRL_DIST_POINTS *
562CRL_DIST_POINTS_new(void)
563{
564 return (CRL_DIST_POINTS *)ASN1_item_new(&CRL_DIST_POINTS_it);
565}
566LCRYPTO_ALIAS(CRL_DIST_POINTS_new);
567
568void
569CRL_DIST_POINTS_free(CRL_DIST_POINTS *a)
570{
571 ASN1_item_free((ASN1_VALUE *)a, &CRL_DIST_POINTS_it);
572}
573LCRYPTO_ALIAS(CRL_DIST_POINTS_free);
574
575static const ASN1_TEMPLATE ISSUING_DIST_POINT_seq_tt[] = {
576 {
577 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
578 .tag = 0,
579 .offset = offsetof(ISSUING_DIST_POINT, distpoint),
580 .field_name = "distpoint",
581 .item = &DIST_POINT_NAME_it,
582 },
583 {
584 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
585 .tag = 1,
586 .offset = offsetof(ISSUING_DIST_POINT, onlyuser),
587 .field_name = "onlyuser",
588 .item = &ASN1_FBOOLEAN_it,
589 },
590 {
591 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
592 .tag = 2,
593 .offset = offsetof(ISSUING_DIST_POINT, onlyCA),
594 .field_name = "onlyCA",
595 .item = &ASN1_FBOOLEAN_it,
596 },
597 {
598 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
599 .tag = 3,
600 .offset = offsetof(ISSUING_DIST_POINT, onlysomereasons),
601 .field_name = "onlysomereasons",
602 .item = &ASN1_BIT_STRING_it,
603 },
604 {
605 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
606 .tag = 4,
607 .offset = offsetof(ISSUING_DIST_POINT, indirectCRL),
608 .field_name = "indirectCRL",
609 .item = &ASN1_FBOOLEAN_it,
610 },
611 {
612 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
613 .tag = 5,
614 .offset = offsetof(ISSUING_DIST_POINT, onlyattr),
615 .field_name = "onlyattr",
616 .item = &ASN1_FBOOLEAN_it,
617 },
618};
619
620const ASN1_ITEM ISSUING_DIST_POINT_it = {
621 .itype = ASN1_ITYPE_SEQUENCE,
622 .utype = V_ASN1_SEQUENCE,
623 .templates = ISSUING_DIST_POINT_seq_tt,
624 .tcount = sizeof(ISSUING_DIST_POINT_seq_tt) / sizeof(ASN1_TEMPLATE),
625 .funcs = NULL,
626 .size = sizeof(ISSUING_DIST_POINT),
627 .sname = "ISSUING_DIST_POINT",
628};
629LCRYPTO_ALIAS(ISSUING_DIST_POINT_it);
630
631
632ISSUING_DIST_POINT *
633d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len)
634{
635 return (ISSUING_DIST_POINT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
636 &ISSUING_DIST_POINT_it);
637}
638LCRYPTO_ALIAS(d2i_ISSUING_DIST_POINT);
639
640int
641i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out)
642{
643 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ISSUING_DIST_POINT_it);
644}
645LCRYPTO_ALIAS(i2d_ISSUING_DIST_POINT);
646
647ISSUING_DIST_POINT *
648ISSUING_DIST_POINT_new(void)
649{
650 return (ISSUING_DIST_POINT *)ASN1_item_new(&ISSUING_DIST_POINT_it);
651}
652LCRYPTO_ALIAS(ISSUING_DIST_POINT_new);
653
654void
655ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a)
656{
657 ASN1_item_free((ASN1_VALUE *)a, &ISSUING_DIST_POINT_it);
658}
659LCRYPTO_ALIAS(ISSUING_DIST_POINT_free);
660
661static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
662 int indent);
663static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
664 STACK_OF(CONF_VALUE) *nval);
665
666static const X509V3_EXT_METHOD x509v3_ext_issuing_distribution_point = {
667 .ext_nid = NID_issuing_distribution_point,
668 .ext_flags = X509V3_EXT_MULTILINE,
669 .it = &ISSUING_DIST_POINT_it,
670 .ext_new = NULL,
671 .ext_free = NULL,
672 .d2i = NULL,
673 .i2d = NULL,
674 .i2s = NULL,
675 .s2i = NULL,
676 .i2v = NULL,
677 .v2i = v2i_idp,
678 .i2r = i2r_idp,
679 .r2i = NULL,
680 .usr_data = NULL,
681};
682
683const X509V3_EXT_METHOD *
684x509v3_ext_method_issuing_distribution_point(void)
685{
686 return &x509v3_ext_issuing_distribution_point;
687}
688
689static void *
690v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
691 STACK_OF(CONF_VALUE) *nval)
692{
693 ISSUING_DIST_POINT *idp = NULL;
694 CONF_VALUE *cnf;
695 char *name, *val;
696 int i, ret;
697
698 idp = ISSUING_DIST_POINT_new();
699 if (!idp)
700 goto merr;
701 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
702 cnf = sk_CONF_VALUE_value(nval, i);
703 name = cnf->name;
704 val = cnf->value;
705 ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
706 if (ret > 0)
707 continue;
708 if (ret < 0)
709 goto err;
710 if (!strcmp(name, "onlyuser")) {
711 if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
712 goto err;
713 }
714 else if (!strcmp(name, "onlyCA")) {
715 if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
716 goto err;
717 }
718 else if (!strcmp(name, "onlyAA")) {
719 if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
720 goto err;
721 }
722 else if (!strcmp(name, "indirectCRL")) {
723 if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
724 goto err;
725 }
726 else if (!strcmp(name, "onlysomereasons")) {
727 if (!set_reasons(&idp->onlysomereasons, val))
728 goto err;
729 } else {
730 X509V3error(X509V3_R_INVALID_NAME);
731 X509V3_conf_err(cnf);
732 goto err;
733 }
734 }
735 return idp;
736
737merr:
738 X509V3error(ERR_R_MALLOC_FAILURE);
739err:
740 ISSUING_DIST_POINT_free(idp);
741 return NULL;
742}
743
744static int
745print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
746{
747 int i;
748
749 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
750 BIO_printf(out, "%*s", indent + 2, "");
751 GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
752 BIO_puts(out, "\n");
753 }
754 return 1;
755}
756
757static int
758print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
759{
760 if (dpn->type == 0) {
761 BIO_printf(out, "%*sFull Name:\n", indent, "");
762 print_gens(out, dpn->name.fullname, indent);
763 } else {
764 X509_NAME ntmp;
765 ntmp.entries = dpn->name.relativename;
766 BIO_printf(out, "%*sRelative Name:\n%*s",
767 indent, "", indent + 2, "");
768 X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
769 BIO_puts(out, "\n");
770 }
771 return 1;
772}
773
774static int
775i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, int indent)
776{
777 ISSUING_DIST_POINT *idp = pidp;
778
779 if (idp->distpoint)
780 print_distpoint(out, idp->distpoint, indent);
781 if (idp->onlyuser > 0)
782 BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
783 if (idp->onlyCA > 0)
784 BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
785 if (idp->indirectCRL > 0)
786 BIO_printf(out, "%*sIndirect CRL\n", indent, "");
787 if (idp->onlysomereasons)
788 print_reasons(out, "Only Some Reasons",
789 idp->onlysomereasons, indent);
790 if (idp->onlyattr > 0)
791 BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
792 if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) &&
793 (idp->indirectCRL <= 0) && !idp->onlysomereasons &&
794 (idp->onlyattr <= 0))
795 BIO_printf(out, "%*s<EMPTY>\n", indent, "");
796
797 return 1;
798}
799
800static int
801i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, int indent)
802{
803 STACK_OF(DIST_POINT) *crld = pcrldp;
804 DIST_POINT *point;
805 int i;
806
807 for (i = 0; i < sk_DIST_POINT_num(crld); i++) {
808 BIO_puts(out, "\n");
809 point = sk_DIST_POINT_value(crld, i);
810 if (point->distpoint)
811 print_distpoint(out, point->distpoint, indent);
812 if (point->reasons)
813 print_reasons(out, "Reasons", point->reasons,
814 indent);
815 if (point->CRLissuer) {
816 BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
817 print_gens(out, point->CRLissuer, indent);
818 }
819 }
820 return 1;
821}
822
823int
824DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
825{
826 int i;
827 STACK_OF(X509_NAME_ENTRY) *frag;
828 X509_NAME_ENTRY *ne;
829
830 if (!dpn || (dpn->type != 1))
831 return 1;
832 frag = dpn->name.relativename;
833 dpn->dpname = X509_NAME_dup(iname);
834 if (!dpn->dpname)
835 return 0;
836 for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
837 ne = sk_X509_NAME_ENTRY_value(frag, i);
838 if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
839 X509_NAME_free(dpn->dpname);
840 dpn->dpname = NULL;
841 return 0;
842 }
843 }
844 /* generate cached encoding of name */
845 if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
846 X509_NAME_free(dpn->dpname);
847 dpn->dpname = NULL;
848 return 0;
849 }
850 return 1;
851}
852LCRYPTO_ALIAS(DIST_POINT_set_dpname);
diff --git a/src/lib/libcrypto/x509/x509_d2.c b/src/lib/libcrypto/x509/x509_d2.c
deleted file mode 100644
index bf358ec299..0000000000
--- a/src/lib/libcrypto/x509/x509_d2.c
+++ /dev/null
@@ -1,131 +0,0 @@
1/* $OpenBSD: x509_d2.c,v 1.12 2023/02/16 08:38:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <sys/uio.h>
61
62#include <openssl/crypto.h>
63#include <openssl/err.h>
64#include <openssl/x509.h>
65
66int
67X509_STORE_set_default_paths(X509_STORE *ctx)
68{
69 X509_LOOKUP *lookup;
70
71 lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
72 if (lookup == NULL)
73 return (0);
74 X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
75
76 lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
77 if (lookup == NULL)
78 return (0);
79 X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
80
81 /* clear any errors */
82 ERR_clear_error();
83
84 return (1);
85}
86LCRYPTO_ALIAS(X509_STORE_set_default_paths);
87
88int
89X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *path)
90{
91 X509_LOOKUP *lookup;
92
93 if (file != NULL) {
94 lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
95 if (lookup == NULL)
96 return (0);
97 if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1)
98 return (0);
99 }
100 if (path != NULL) {
101 lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
102 if (lookup == NULL)
103 return (0);
104 if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
105 return (0);
106 }
107 if ((path == NULL) && (file == NULL))
108 return (0);
109 return (1);
110}
111LCRYPTO_ALIAS(X509_STORE_load_locations);
112
113int
114X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len)
115{
116 X509_LOOKUP *lookup;
117 struct iovec iov;
118
119 lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_mem());
120 if (lookup == NULL)
121 return (0);
122
123 iov.iov_base = buf;
124 iov.iov_len = len;
125
126 if (X509_LOOKUP_add_mem(lookup, &iov, X509_FILETYPE_PEM) != 1)
127 return (0);
128
129 return (1);
130}
131LCRYPTO_ALIAS(X509_STORE_load_mem);
diff --git a/src/lib/libcrypto/x509/x509_def.c b/src/lib/libcrypto/x509/x509_def.c
deleted file mode 100644
index f9b395c206..0000000000
--- a/src/lib/libcrypto/x509/x509_def.c
+++ /dev/null
@@ -1,103 +0,0 @@
1/* $OpenBSD: x509_def.c,v 1.10 2024/11/05 09:35:40 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/x509.h>
60
61#include "crypto_local.h"
62
63const char *
64X509_get_default_private_dir(void)
65{
66 return X509_PRIVATE_DIR;
67}
68LCRYPTO_ALIAS(X509_get_default_private_dir);
69
70const char *
71X509_get_default_cert_area(void)
72{
73 return X509_CERT_AREA;
74}
75LCRYPTO_ALIAS(X509_get_default_cert_area);
76
77const char *
78X509_get_default_cert_dir(void)
79{
80 return X509_CERT_DIR;
81}
82LCRYPTO_ALIAS(X509_get_default_cert_dir);
83
84const char *
85X509_get_default_cert_file(void)
86{
87 return X509_CERT_FILE;
88}
89LCRYPTO_ALIAS(X509_get_default_cert_file);
90
91const char *
92X509_get_default_cert_dir_env(void)
93{
94 return X509_CERT_DIR_EVP;
95}
96LCRYPTO_ALIAS(X509_get_default_cert_dir_env);
97
98const char *
99X509_get_default_cert_file_env(void)
100{
101 return X509_CERT_FILE_EVP;
102}
103LCRYPTO_ALIAS(X509_get_default_cert_file_env);
diff --git a/src/lib/libcrypto/x509/x509_err.c b/src/lib/libcrypto/x509/x509_err.c
deleted file mode 100644
index cff045b105..0000000000
--- a/src/lib/libcrypto/x509/x509_err.c
+++ /dev/null
@@ -1,215 +0,0 @@
1/* $OpenBSD: x509_err.c,v 1.23 2024/06/24 06:43:23 tb Exp $ */
2/* ====================================================================
3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <stdio.h>
57
58#include <openssl/opensslconf.h>
59
60#include <openssl/err.h>
61#include <openssl/x509.h>
62#include <openssl/x509v3.h>
63
64#include "err_local.h"
65
66#ifndef OPENSSL_NO_ERR
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason)
70
71static const ERR_STRING_DATA X509_str_functs[] = {
72 {ERR_FUNC(0xfff), "CRYPTO_internal"},
73 {0, NULL}
74};
75
76static const ERR_STRING_DATA X509_str_reasons[] = {
77 {ERR_REASON(X509_R_BAD_X509_FILETYPE) , "bad x509 filetype"},
78 {ERR_REASON(X509_R_BASE64_DECODE_ERROR) , "base64 decode error"},
79 {ERR_REASON(X509_R_CANT_CHECK_DH_KEY) , "cant check dh key"},
80 {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE), "cert already in hash table"},
81 {ERR_REASON(X509_R_ERR_ASN1_LIB) , "err asn1 lib"},
82 {ERR_REASON(X509_R_INVALID_DIRECTORY) , "invalid directory"},
83 {ERR_REASON(X509_R_INVALID_FIELD_NAME) , "invalid field name"},
84 {ERR_REASON(X509_R_INVALID_TRUST) , "invalid trust"},
85 {ERR_REASON(X509_R_INVALID_VERSION) , "invalid x509 version"},
86 {ERR_REASON(X509_R_KEY_TYPE_MISMATCH) , "key type mismatch"},
87 {ERR_REASON(X509_R_KEY_VALUES_MISMATCH) , "key values mismatch"},
88 {ERR_REASON(X509_R_LOADING_CERT_DIR) , "loading cert dir"},
89 {ERR_REASON(X509_R_LOADING_DEFAULTS) , "loading defaults"},
90 {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED) , "method not supported"},
91 {ERR_REASON(X509_R_NO_CERTIFICATE_OR_CRL_FOUND), "no certificate or crl found"},
92 {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), "no cert set for us to verify"},
93 {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"},
94 {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"},
95 {ERR_REASON(X509_R_SHOULD_RETRY) , "should retry"},
96 {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), "unable to find parameters in chain"},
97 {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), "unable to get certs public key"},
98 {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE) , "unknown key type"},
99 {ERR_REASON(X509_R_UNKNOWN_NID) , "unknown nid"},
100 {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID) , "unknown purpose id"},
101 {ERR_REASON(X509_R_UNKNOWN_TRUST_ID) , "unknown trust id"},
102 {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
103 {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE) , "wrong lookup type"},
104 {ERR_REASON(X509_R_WRONG_TYPE) , "wrong type"},
105 {0, NULL}
106};
107
108#undef ERR_FUNC
109#undef ERR_REASON
110#define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0)
111#define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason)
112
113static const ERR_STRING_DATA X509V3_str_functs[] = {
114 {ERR_FUNC(0xfff), "CRYPTO_internal"},
115 {0, NULL}
116};
117
118static const ERR_STRING_DATA X509V3_str_reasons[] = {
119 {ERR_REASON(X509V3_R_BAD_IP_ADDRESS) , "bad ip address"},
120 {ERR_REASON(X509V3_R_BAD_OBJECT) , "bad object"},
121 {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR) , "bn dec2bn error"},
122 {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR), "bn to asn1 integer error"},
123 {ERR_REASON(X509V3_R_DIRNAME_ERROR) , "dirname error"},
124 {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"},
125 {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID) , "duplicate zone id"},
126 {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"},
127 {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION), "error creating extension"},
128 {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION) , "error in extension"},
129 {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"},
130 {ERR_REASON(X509V3_R_EXTENSION_EXISTS) , "extension exists"},
131 {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"},
132 {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"},
133 {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), "extension setting not supported"},
134 {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"},
135 {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"},
136 {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT) , "illegal hex digit"},
137 {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), "incorrect policy syntax tag"},
138 {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"},
139 {ERR_REASON(X509V3_R_INVALID_ASNUMBER) , "invalid asnumber"},
140 {ERR_REASON(X509V3_R_INVALID_ASRANGE) , "invalid asrange"},
141 {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"},
142 {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING), "invalid extension string"},
143 {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"},
144 {ERR_REASON(X509V3_R_INVALID_IPADDRESS) , "invalid ipaddress"},
145 {ERR_REASON(X509V3_R_INVALID_NAME) , "invalid name"},
146 {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"},
147 {ERR_REASON(X509V3_R_INVALID_NULL_NAME) , "invalid null name"},
148 {ERR_REASON(X509V3_R_INVALID_NULL_VALUE) , "invalid null value"},
149 {ERR_REASON(X509V3_R_INVALID_NUMBER) , "invalid number"},
150 {ERR_REASON(X509V3_R_INVALID_NUMBERS) , "invalid numbers"},
151 {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER), "invalid object identifier"},
152 {ERR_REASON(X509V3_R_INVALID_OPTION) , "invalid option"},
153 {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER), "invalid policy identifier"},
154 {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING), "invalid proxy policy setting"},
155 {ERR_REASON(X509V3_R_INVALID_PURPOSE) , "invalid purpose"},
156 {ERR_REASON(X509V3_R_INVALID_SAFI) , "invalid safi"},
157 {ERR_REASON(X509V3_R_INVALID_SECTION) , "invalid section"},
158 {ERR_REASON(X509V3_R_INVALID_SYNTAX) , "invalid syntax"},
159 {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"},
160 {ERR_REASON(X509V3_R_MISSING_VALUE) , "missing value"},
161 {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), "need organization and numbers"},
162 {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE) , "no config database"},
163 {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"},
164 {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS) , "no issuer details"},
165 {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"},
166 {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), "no proxy cert policy language defined"},
167 {ERR_REASON(X509V3_R_NO_PUBLIC_KEY) , "no public key"},
168 {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS) , "no subject details"},
169 {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"},
170 {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"},
171 {ERR_REASON(X509V3_R_OTHERNAME_ERROR) , "othername error"},
172 {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), "policy language already defined"},
173 {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH) , "policy path length"},
174 {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), "policy path length already defined"},
175 {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED), "policy syntax not currently supported"},
176 {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), "policy when proxy language requires no policy"},
177 {ERR_REASON(X509V3_R_SECTION_NOT_FOUND) , "section not found"},
178 {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), "unable to get issuer details"},
179 {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), "unable to get issuer keyid"},
180 {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), "unknown bit string argument"},
181 {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION) , "unknown extension"},
182 {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"},
183 {ERR_REASON(X509V3_R_UNKNOWN_OPTION) , "unknown option"},
184 {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION) , "unsupported option"},
185 {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE) , "unsupported type"},
186 {ERR_REASON(X509V3_R_USER_TOO_LONG) , "user too long"},
187 {0, NULL}
188};
189
190#endif
191
192void
193ERR_load_X509_strings(void)
194{
195#ifndef OPENSSL_NO_ERR
196 if (ERR_func_error_string(X509_str_functs[0].error) == NULL) {
197 ERR_load_const_strings(X509_str_functs);
198 ERR_load_const_strings(X509_str_reasons);
199 }
200#endif
201}
202LCRYPTO_ALIAS(ERR_load_X509_strings);
203
204
205void
206ERR_load_X509V3_strings(void)
207{
208#ifndef OPENSSL_NO_ERR
209 if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) {
210 ERR_load_const_strings(X509V3_str_functs);
211 ERR_load_const_strings(X509V3_str_reasons);
212 }
213#endif
214}
215LCRYPTO_ALIAS(ERR_load_X509V3_strings);
diff --git a/src/lib/libcrypto/x509/x509_ext.c b/src/lib/libcrypto/x509/x509_ext.c
deleted file mode 100644
index f9a311feff..0000000000
--- a/src/lib/libcrypto/x509/x509_ext.c
+++ /dev/null
@@ -1,258 +0,0 @@
1/* $OpenBSD: x509_ext.c,v 1.18 2024/05/14 07:39:43 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/x509.h>
62#include <openssl/x509v3.h>
63
64#include "x509_local.h"
65
66int
67X509_CRL_get_ext_count(const X509_CRL *x)
68{
69 return X509v3_get_ext_count(x->crl->extensions);
70}
71LCRYPTO_ALIAS(X509_CRL_get_ext_count);
72
73int
74X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos)
75{
76 return X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos);
77}
78LCRYPTO_ALIAS(X509_CRL_get_ext_by_NID);
79
80int
81X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, int lastpos)
82{
83 return X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos);
84}
85LCRYPTO_ALIAS(X509_CRL_get_ext_by_OBJ);
86
87int
88X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos)
89{
90 return X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos);
91}
92LCRYPTO_ALIAS(X509_CRL_get_ext_by_critical);
93
94X509_EXTENSION *
95X509_CRL_get_ext(const X509_CRL *x, int loc)
96{
97 return X509v3_get_ext(x->crl->extensions, loc);
98}
99LCRYPTO_ALIAS(X509_CRL_get_ext);
100
101X509_EXTENSION *
102X509_CRL_delete_ext(X509_CRL *x, int loc)
103{
104 return X509v3_delete_ext(x->crl->extensions, loc);
105}
106LCRYPTO_ALIAS(X509_CRL_delete_ext);
107
108void *
109X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx)
110{
111 return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
112}
113LCRYPTO_ALIAS(X509_CRL_get_ext_d2i);
114
115int
116X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
117 unsigned long flags)
118{
119 return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
120}
121LCRYPTO_ALIAS(X509_CRL_add1_ext_i2d);
122
123int
124X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
125{
126 return X509v3_add_ext(&x->crl->extensions, ex, loc) != NULL;
127}
128LCRYPTO_ALIAS(X509_CRL_add_ext);
129
130int
131X509_get_ext_count(const X509 *x)
132{
133 return X509v3_get_ext_count(x->cert_info->extensions);
134}
135LCRYPTO_ALIAS(X509_get_ext_count);
136
137int
138X509_get_ext_by_NID(const X509 *x, int nid, int lastpos)
139{
140 return X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos);
141}
142LCRYPTO_ALIAS(X509_get_ext_by_NID);
143
144int
145X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos)
146{
147 return X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos);
148}
149LCRYPTO_ALIAS(X509_get_ext_by_OBJ);
150
151int
152X509_get_ext_by_critical(const X509 *x, int crit, int lastpos)
153{
154 return X509v3_get_ext_by_critical(x->cert_info->extensions, crit,
155 lastpos);
156}
157LCRYPTO_ALIAS(X509_get_ext_by_critical);
158
159X509_EXTENSION *
160X509_get_ext(const X509 *x, int loc)
161{
162 return X509v3_get_ext(x->cert_info->extensions, loc);
163}
164LCRYPTO_ALIAS(X509_get_ext);
165
166X509_EXTENSION *
167X509_delete_ext(X509 *x, int loc)
168{
169 return X509v3_delete_ext(x->cert_info->extensions, loc);
170}
171LCRYPTO_ALIAS(X509_delete_ext);
172
173int
174X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
175{
176 return X509v3_add_ext(&x->cert_info->extensions, ex, loc) != NULL;
177}
178LCRYPTO_ALIAS(X509_add_ext);
179
180void *
181X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx)
182{
183 return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
184}
185LCRYPTO_ALIAS(X509_get_ext_d2i);
186
187int
188X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, unsigned long flags)
189{
190 return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
191 flags);
192}
193LCRYPTO_ALIAS(X509_add1_ext_i2d);
194
195int
196X509_REVOKED_get_ext_count(const X509_REVOKED *x)
197{
198 return X509v3_get_ext_count(x->extensions);
199}
200LCRYPTO_ALIAS(X509_REVOKED_get_ext_count);
201
202int
203X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos)
204{
205 return X509v3_get_ext_by_NID(x->extensions, nid, lastpos);
206}
207LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_NID);
208
209int
210X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj,
211 int lastpos)
212{
213 return X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos);
214}
215LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_OBJ);
216
217int
218X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos)
219{
220 return X509v3_get_ext_by_critical(x->extensions, crit, lastpos);
221}
222LCRYPTO_ALIAS(X509_REVOKED_get_ext_by_critical);
223
224X509_EXTENSION *
225X509_REVOKED_get_ext(const X509_REVOKED *x, int loc)
226{
227 return X509v3_get_ext(x->extensions, loc);
228}
229LCRYPTO_ALIAS(X509_REVOKED_get_ext);
230
231X509_EXTENSION *
232X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
233{
234 return X509v3_delete_ext(x->extensions, loc);
235}
236LCRYPTO_ALIAS(X509_REVOKED_delete_ext);
237
238int
239X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
240{
241 return X509v3_add_ext(&x->extensions, ex, loc) != NULL;
242}
243LCRYPTO_ALIAS(X509_REVOKED_add_ext);
244
245void *
246X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, int *idx)
247{
248 return X509V3_get_d2i(x->extensions, nid, crit, idx);
249}
250LCRYPTO_ALIAS(X509_REVOKED_get_ext_d2i);
251
252int
253X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
254 unsigned long flags)
255{
256 return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
257}
258LCRYPTO_ALIAS(X509_REVOKED_add1_ext_i2d);
diff --git a/src/lib/libcrypto/x509/x509_extku.c b/src/lib/libcrypto/x509/x509_extku.c
deleted file mode 100644
index da5036a09a..0000000000
--- a/src/lib/libcrypto/x509/x509_extku.c
+++ /dev/null
@@ -1,236 +0,0 @@
1/* $OpenBSD: x509_extku.c,v 1.6 2024/08/31 10:03:03 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60
61#include <openssl/asn1t.h>
62#include <openssl/conf.h>
63#include <openssl/err.h>
64#include <openssl/x509v3.h>
65
66#include "x509_local.h"
67
68static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
69 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
70static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(
71 const X509V3_EXT_METHOD *method, void *eku, STACK_OF(CONF_VALUE) *extlist);
72
73static const X509V3_EXT_METHOD x509v3_ext_ext_key_usage = {
74 .ext_nid = NID_ext_key_usage,
75 .ext_flags = 0,
76 .it = &EXTENDED_KEY_USAGE_it,
77 .ext_new = NULL,
78 .ext_free = NULL,
79 .d2i = NULL,
80 .i2d = NULL,
81 .i2s = NULL,
82 .s2i = NULL,
83 .i2v = i2v_EXTENDED_KEY_USAGE,
84 .v2i = v2i_EXTENDED_KEY_USAGE,
85 .i2r = NULL,
86 .r2i = NULL,
87 .usr_data = NULL,
88};
89
90const X509V3_EXT_METHOD *
91x509v3_ext_method_ext_key_usage(void)
92{
93 return &x509v3_ext_ext_key_usage;
94}
95
96/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
97static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_acceptableResponses = {
98 .ext_nid = NID_id_pkix_OCSP_acceptableResponses,
99 .ext_flags = 0,
100 .it = &EXTENDED_KEY_USAGE_it,
101 .ext_new = NULL,
102 .ext_free = NULL,
103 .d2i = NULL,
104 .i2d = NULL,
105 .i2s = NULL,
106 .s2i = NULL,
107 .i2v = i2v_EXTENDED_KEY_USAGE,
108 .v2i = v2i_EXTENDED_KEY_USAGE,
109 .i2r = NULL,
110 .r2i = NULL,
111 .usr_data = NULL,
112};
113
114const X509V3_EXT_METHOD *
115x509v3_ext_method_id_pkix_OCSP_acceptableResponses(void)
116{
117 return &x509v3_ext_id_pkix_OCSP_acceptableResponses;
118}
119
120static const ASN1_TEMPLATE EXTENDED_KEY_USAGE_item_tt = {
121 .flags = ASN1_TFLG_SEQUENCE_OF,
122 .tag = 0,
123 .offset = 0,
124 .field_name = "EXTENDED_KEY_USAGE",
125 .item = &ASN1_OBJECT_it,
126};
127
128const ASN1_ITEM EXTENDED_KEY_USAGE_it = {
129 .itype = ASN1_ITYPE_PRIMITIVE,
130 .utype = -1,
131 .templates = &EXTENDED_KEY_USAGE_item_tt,
132 .tcount = 0,
133 .funcs = NULL,
134 .size = 0,
135 .sname = "EXTENDED_KEY_USAGE",
136};
137LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_it);
138
139
140EXTENDED_KEY_USAGE *
141d2i_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE **a, const unsigned char **in, long len)
142{
143 return (EXTENDED_KEY_USAGE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
144 &EXTENDED_KEY_USAGE_it);
145}
146LCRYPTO_ALIAS(d2i_EXTENDED_KEY_USAGE);
147
148int
149i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out)
150{
151 return ASN1_item_i2d((ASN1_VALUE *)a, out, &EXTENDED_KEY_USAGE_it);
152}
153LCRYPTO_ALIAS(i2d_EXTENDED_KEY_USAGE);
154
155EXTENDED_KEY_USAGE *
156EXTENDED_KEY_USAGE_new(void)
157{
158 return (EXTENDED_KEY_USAGE *)ASN1_item_new(&EXTENDED_KEY_USAGE_it);
159}
160LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_new);
161
162void
163EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a)
164{
165 ASN1_item_free((ASN1_VALUE *)a, &EXTENDED_KEY_USAGE_it);
166}
167LCRYPTO_ALIAS(EXTENDED_KEY_USAGE_free);
168
169static STACK_OF(CONF_VALUE) *
170i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, void *a,
171 STACK_OF(CONF_VALUE) *extlist)
172{
173 ASN1_OBJECT *obj;
174 EXTENDED_KEY_USAGE *eku = a;
175 STACK_OF(CONF_VALUE) *free_extlist = NULL;
176 char obj_tmp[80];
177 int i;
178
179 if (extlist == NULL) {
180 if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
181 return NULL;
182 }
183
184 for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
185 if ((obj = sk_ASN1_OBJECT_value(eku, i)) == NULL)
186 goto err;
187 if (!i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, obj))
188 goto err;
189 if (!X509V3_add_value(NULL, obj_tmp, &extlist))
190 goto err;
191 }
192
193 return extlist;
194
195 err:
196 sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
197
198 return NULL;
199}
200
201static void *
202v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
203 STACK_OF(CONF_VALUE) *nval)
204{
205 EXTENDED_KEY_USAGE *extku;
206 char *extval;
207 ASN1_OBJECT *objtmp;
208 CONF_VALUE *val;
209 int i;
210
211 if (!(extku = sk_ASN1_OBJECT_new_null())) {
212 X509V3error(ERR_R_MALLOC_FAILURE);
213 return NULL;
214 }
215
216 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
217 val = sk_CONF_VALUE_value(nval, i);
218 if (val->value)
219 extval = val->value;
220 else
221 extval = val->name;
222 if (!(objtmp = OBJ_txt2obj(extval, 0))) {
223 sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
224 X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
225 X509V3_conf_err(val);
226 return NULL;
227 }
228 if (sk_ASN1_OBJECT_push(extku, objtmp) == 0) {
229 ASN1_OBJECT_free(objtmp);
230 sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
231 X509V3error(ERR_R_MALLOC_FAILURE);
232 return NULL;
233 }
234 }
235 return extku;
236}
diff --git a/src/lib/libcrypto/x509/x509_genn.c b/src/lib/libcrypto/x509/x509_genn.c
deleted file mode 100644
index 1ea7155795..0000000000
--- a/src/lib/libcrypto/x509/x509_genn.c
+++ /dev/null
@@ -1,541 +0,0 @@
1/* $OpenBSD: x509_genn.c,v 1.7 2024/07/08 14:47:44 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2008 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 */
58
59
60#include <stdio.h>
61
62#include <openssl/asn1t.h>
63#include <openssl/conf.h>
64#include <openssl/x509v3.h>
65
66static const ASN1_TEMPLATE OTHERNAME_seq_tt[] = {
67 {
68 .flags = 0,
69 .tag = 0,
70 .offset = offsetof(OTHERNAME, type_id),
71 .field_name = "type_id",
72 .item = &ASN1_OBJECT_it,
73 },
74 /* Maybe have a true ANY DEFINED BY later */
75 {
76 .flags = ASN1_TFLG_EXPLICIT,
77 .tag = 0,
78 .offset = offsetof(OTHERNAME, value),
79 .field_name = "value",
80 .item = &ASN1_ANY_it,
81 },
82};
83
84const ASN1_ITEM OTHERNAME_it = {
85 .itype = ASN1_ITYPE_SEQUENCE,
86 .utype = V_ASN1_SEQUENCE,
87 .templates = OTHERNAME_seq_tt,
88 .tcount = sizeof(OTHERNAME_seq_tt) / sizeof(ASN1_TEMPLATE),
89 .funcs = NULL,
90 .size = sizeof(OTHERNAME),
91 .sname = "OTHERNAME",
92};
93LCRYPTO_ALIAS(OTHERNAME_it);
94
95
96OTHERNAME *
97d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len)
98{
99 return (OTHERNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
100 &OTHERNAME_it);
101}
102LCRYPTO_ALIAS(d2i_OTHERNAME);
103
104int
105i2d_OTHERNAME(OTHERNAME *a, unsigned char **out)
106{
107 return ASN1_item_i2d((ASN1_VALUE *)a, out, &OTHERNAME_it);
108}
109LCRYPTO_ALIAS(i2d_OTHERNAME);
110
111OTHERNAME *
112OTHERNAME_new(void)
113{
114 return (OTHERNAME *)ASN1_item_new(&OTHERNAME_it);
115}
116LCRYPTO_ALIAS(OTHERNAME_new);
117
118void
119OTHERNAME_free(OTHERNAME *a)
120{
121 ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it);
122}
123LCRYPTO_ALIAS(OTHERNAME_free);
124
125/* Uses explicit tagging since DIRECTORYSTRING is a CHOICE type */
126static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = {
127 {
128 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
129 .tag = 0,
130 .offset = offsetof(EDIPARTYNAME, nameAssigner),
131 .field_name = "nameAssigner",
132 .item = &DIRECTORYSTRING_it,
133 },
134 {
135 .flags = ASN1_TFLG_EXPLICIT,
136 .tag = 1,
137 .offset = offsetof(EDIPARTYNAME, partyName),
138 .field_name = "partyName",
139 .item = &DIRECTORYSTRING_it,
140 },
141};
142
143const ASN1_ITEM EDIPARTYNAME_it = {
144 .itype = ASN1_ITYPE_SEQUENCE,
145 .utype = V_ASN1_SEQUENCE,
146 .templates = EDIPARTYNAME_seq_tt,
147 .tcount = sizeof(EDIPARTYNAME_seq_tt) / sizeof(ASN1_TEMPLATE),
148 .funcs = NULL,
149 .size = sizeof(EDIPARTYNAME),
150 .sname = "EDIPARTYNAME",
151};
152LCRYPTO_ALIAS(EDIPARTYNAME_it);
153
154
155EDIPARTYNAME *
156d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len)
157{
158 return (EDIPARTYNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
159 &EDIPARTYNAME_it);
160}
161LCRYPTO_ALIAS(d2i_EDIPARTYNAME);
162
163int
164i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out)
165{
166 return ASN1_item_i2d((ASN1_VALUE *)a, out, &EDIPARTYNAME_it);
167}
168LCRYPTO_ALIAS(i2d_EDIPARTYNAME);
169
170EDIPARTYNAME *
171EDIPARTYNAME_new(void)
172{
173 return (EDIPARTYNAME *)ASN1_item_new(&EDIPARTYNAME_it);
174}
175LCRYPTO_ALIAS(EDIPARTYNAME_new);
176
177void
178EDIPARTYNAME_free(EDIPARTYNAME *a)
179{
180 ASN1_item_free((ASN1_VALUE *)a, &EDIPARTYNAME_it);
181}
182LCRYPTO_ALIAS(EDIPARTYNAME_free);
183
184static const ASN1_TEMPLATE GENERAL_NAME_ch_tt[] = {
185 {
186 .flags = ASN1_TFLG_IMPLICIT,
187 .tag = GEN_OTHERNAME,
188 .offset = offsetof(GENERAL_NAME, d.otherName),
189 .field_name = "d.otherName",
190 .item = &OTHERNAME_it,
191 },
192 {
193 .flags = ASN1_TFLG_IMPLICIT,
194 .tag = GEN_EMAIL,
195 .offset = offsetof(GENERAL_NAME, d.rfc822Name),
196 .field_name = "d.rfc822Name",
197 .item = &ASN1_IA5STRING_it,
198 },
199 {
200 .flags = ASN1_TFLG_IMPLICIT,
201 .tag = GEN_DNS,
202 .offset = offsetof(GENERAL_NAME, d.dNSName),
203 .field_name = "d.dNSName",
204 .item = &ASN1_IA5STRING_it,
205 },
206 /* Don't decode this */
207 {
208 .flags = ASN1_TFLG_IMPLICIT,
209 .tag = GEN_X400,
210 .offset = offsetof(GENERAL_NAME, d.x400Address),
211 .field_name = "d.x400Address",
212 .item = &ASN1_SEQUENCE_it,
213 },
214 /* X509_NAME is a CHOICE type so use EXPLICIT */
215 {
216 .flags = ASN1_TFLG_EXPLICIT,
217 .tag = GEN_DIRNAME,
218 .offset = offsetof(GENERAL_NAME, d.directoryName),
219 .field_name = "d.directoryName",
220 .item = &X509_NAME_it,
221 },
222 {
223 .flags = ASN1_TFLG_IMPLICIT,
224 .tag = GEN_EDIPARTY,
225 .offset = offsetof(GENERAL_NAME, d.ediPartyName),
226 .field_name = "d.ediPartyName",
227 .item = &EDIPARTYNAME_it,
228 },
229 {
230 .flags = ASN1_TFLG_IMPLICIT,
231 .tag = GEN_URI,
232 .offset = offsetof(GENERAL_NAME, d.uniformResourceIdentifier),
233 .field_name = "d.uniformResourceIdentifier",
234 .item = &ASN1_IA5STRING_it,
235 },
236 {
237 .flags = ASN1_TFLG_IMPLICIT,
238 .tag = GEN_IPADD,
239 .offset = offsetof(GENERAL_NAME, d.iPAddress),
240 .field_name = "d.iPAddress",
241 .item = &ASN1_OCTET_STRING_it,
242 },
243 {
244 .flags = ASN1_TFLG_IMPLICIT,
245 .tag = GEN_RID,
246 .offset = offsetof(GENERAL_NAME, d.registeredID),
247 .field_name = "d.registeredID",
248 .item = &ASN1_OBJECT_it,
249 },
250};
251
252const ASN1_ITEM GENERAL_NAME_it = {
253 .itype = ASN1_ITYPE_CHOICE,
254 .utype = offsetof(GENERAL_NAME, type),
255 .templates = GENERAL_NAME_ch_tt,
256 .tcount = sizeof(GENERAL_NAME_ch_tt) / sizeof(ASN1_TEMPLATE),
257 .funcs = NULL,
258 .size = sizeof(GENERAL_NAME),
259 .sname = "GENERAL_NAME",
260};
261LCRYPTO_ALIAS(GENERAL_NAME_it);
262
263
264GENERAL_NAME *
265d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len)
266{
267 return (GENERAL_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
268 &GENERAL_NAME_it);
269}
270LCRYPTO_ALIAS(d2i_GENERAL_NAME);
271
272int
273i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out)
274{
275 return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAME_it);
276}
277LCRYPTO_ALIAS(i2d_GENERAL_NAME);
278
279GENERAL_NAME *
280GENERAL_NAME_new(void)
281{
282 return (GENERAL_NAME *)ASN1_item_new(&GENERAL_NAME_it);
283}
284LCRYPTO_ALIAS(GENERAL_NAME_new);
285
286void
287GENERAL_NAME_free(GENERAL_NAME *a)
288{
289 ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAME_it);
290}
291LCRYPTO_ALIAS(GENERAL_NAME_free);
292
293static const ASN1_TEMPLATE GENERAL_NAMES_item_tt = {
294 .flags = ASN1_TFLG_SEQUENCE_OF,
295 .tag = 0,
296 .offset = 0,
297 .field_name = "GeneralNames",
298 .item = &GENERAL_NAME_it,
299};
300
301const ASN1_ITEM GENERAL_NAMES_it = {
302 .itype = ASN1_ITYPE_PRIMITIVE,
303 .utype = -1,
304 .templates = &GENERAL_NAMES_item_tt,
305 .tcount = 0,
306 .funcs = NULL,
307 .size = 0,
308 .sname = "GENERAL_NAMES",
309};
310LCRYPTO_ALIAS(GENERAL_NAMES_it);
311
312
313GENERAL_NAMES *
314d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len)
315{
316 return (GENERAL_NAMES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
317 &GENERAL_NAMES_it);
318}
319LCRYPTO_ALIAS(d2i_GENERAL_NAMES);
320
321int
322i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out)
323{
324 return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAMES_it);
325}
326LCRYPTO_ALIAS(i2d_GENERAL_NAMES);
327
328GENERAL_NAMES *
329GENERAL_NAMES_new(void)
330{
331 return (GENERAL_NAMES *)ASN1_item_new(&GENERAL_NAMES_it);
332}
333LCRYPTO_ALIAS(GENERAL_NAMES_new);
334
335void
336GENERAL_NAMES_free(GENERAL_NAMES *a)
337{
338 ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAMES_it);
339}
340LCRYPTO_ALIAS(GENERAL_NAMES_free);
341
342GENERAL_NAME *
343GENERAL_NAME_dup(GENERAL_NAME *a)
344{
345 return ASN1_item_dup(&GENERAL_NAME_it, a);
346}
347LCRYPTO_ALIAS(GENERAL_NAME_dup);
348
349static int
350EDIPARTYNAME_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b)
351{
352 int res;
353
354 /*
355 * Shouldn't be possible in a valid GENERAL_NAME, but we handle it
356 * anyway. OTHERNAME_cmp treats NULL != NULL, so we do the same here.
357 */
358 if (a == NULL || b == NULL)
359 return -1;
360 if (a->nameAssigner == NULL && b->nameAssigner != NULL)
361 return -1;
362 if (a->nameAssigner != NULL && b->nameAssigner == NULL)
363 return 1;
364 /* If we get here, both have nameAssigner set or both unset. */
365 if (a->nameAssigner != NULL) {
366 res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner);
367 if (res != 0)
368 return res;
369 }
370 /*
371 * partyName is required, so these should never be NULL. We treat it in
372 * the same way as the a == NULL || b == NULL case above.
373 */
374 if (a->partyName == NULL || b->partyName == NULL)
375 return -1;
376
377 return ASN1_STRING_cmp(a->partyName, b->partyName);
378}
379
380/* Returns 0 if they are equal, != 0 otherwise. */
381int
382GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
383{
384 int result = -1;
385
386 if (!a || !b || a->type != b->type)
387 return -1;
388 switch (a->type) {
389 case GEN_X400:
390 result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address);
391 break;
392
393 case GEN_EDIPARTY:
394 result = EDIPARTYNAME_cmp(a->d.ediPartyName, b->d.ediPartyName);
395 break;
396
397 case GEN_OTHERNAME:
398 result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
399 break;
400
401 case GEN_EMAIL:
402 case GEN_DNS:
403 case GEN_URI:
404 result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
405 break;
406
407 case GEN_DIRNAME:
408 result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
409 break;
410
411 case GEN_IPADD:
412 result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
413 break;
414
415 case GEN_RID:
416 result = OBJ_cmp(a->d.rid, b->d.rid);
417 break;
418 }
419 return result;
420}
421LCRYPTO_ALIAS(GENERAL_NAME_cmp);
422
423/* Returns 0 if they are equal, != 0 otherwise. */
424int
425OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
426{
427 int result = -1;
428
429 if (!a || !b)
430 return -1;
431 /* Check their type first. */
432 if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
433 return result;
434 /* Check the value. */
435 result = ASN1_TYPE_cmp(a->value, b->value);
436 return result;
437}
438LCRYPTO_ALIAS(OTHERNAME_cmp);
439
440void
441GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
442{
443 switch (type) {
444 case GEN_X400:
445 a->d.x400Address = value;
446 break;
447
448 case GEN_EDIPARTY:
449 a->d.ediPartyName = value;
450 break;
451
452 case GEN_OTHERNAME:
453 a->d.otherName = value;
454 break;
455
456 case GEN_EMAIL:
457 case GEN_DNS:
458 case GEN_URI:
459 a->d.ia5 = value;
460 break;
461
462 case GEN_DIRNAME:
463 a->d.dirn = value;
464 break;
465
466 case GEN_IPADD:
467 a->d.ip = value;
468 break;
469
470 case GEN_RID:
471 a->d.rid = value;
472 break;
473 }
474 a->type = type;
475}
476LCRYPTO_ALIAS(GENERAL_NAME_set0_value);
477
478void *
479GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
480{
481 if (ptype)
482 *ptype = a->type;
483 switch (a->type) {
484 case GEN_X400:
485 return a->d.x400Address;
486
487 case GEN_EDIPARTY:
488 return a->d.ediPartyName;
489
490 case GEN_OTHERNAME:
491 return a->d.otherName;
492
493 case GEN_EMAIL:
494 case GEN_DNS:
495 case GEN_URI:
496 return a->d.ia5;
497
498 case GEN_DIRNAME:
499 return a->d.dirn;
500
501 case GEN_IPADD:
502 return a->d.ip;
503
504 case GEN_RID:
505 return a->d.rid;
506
507 default:
508 return NULL;
509 }
510}
511LCRYPTO_ALIAS(GENERAL_NAME_get0_value);
512
513int
514GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid,
515 ASN1_TYPE *value)
516{
517 OTHERNAME *oth;
518
519 oth = OTHERNAME_new();
520 if (!oth)
521 return 0;
522 oth->type_id = oid;
523 oth->value = value;
524 GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
525 return 1;
526}
527LCRYPTO_ALIAS(GENERAL_NAME_set0_othername);
528
529int
530GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, ASN1_OBJECT **poid,
531 ASN1_TYPE **pvalue)
532{
533 if (gen->type != GEN_OTHERNAME)
534 return 0;
535 if (poid)
536 *poid = gen->d.otherName->type_id;
537 if (pvalue)
538 *pvalue = gen->d.otherName->value;
539 return 1;
540}
541LCRYPTO_ALIAS(GENERAL_NAME_get0_otherName);
diff --git a/src/lib/libcrypto/x509/x509_ia5.c b/src/lib/libcrypto/x509/x509_ia5.c
deleted file mode 100644
index 4f62a9134c..0000000000
--- a/src/lib/libcrypto/x509/x509_ia5.c
+++ /dev/null
@@ -1,268 +0,0 @@
1/* $OpenBSD: x509_ia5.c,v 1.2 2024/07/13 15:08:58 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/conf.h>
64#include <openssl/err.h>
65#include <openssl/x509v3.h>
66
67static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5);
68static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
69 X509V3_CTX *ctx, char *str);
70
71static const X509V3_EXT_METHOD x509v3_ext_netscape_base_url = {
72 .ext_nid = NID_netscape_base_url,
73 .ext_flags = 0,
74 .it = &ASN1_IA5STRING_it,
75 .ext_new = NULL,
76 .ext_free = NULL,
77 .d2i = NULL,
78 .i2d = NULL,
79 .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING,
80 .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING,
81 .i2v = NULL,
82 .v2i = NULL,
83 .i2r = NULL,
84 .r2i = NULL,
85 .usr_data = NULL,
86};
87
88const X509V3_EXT_METHOD *
89x509v3_ext_method_netscape_base_url(void)
90{
91 return &x509v3_ext_netscape_base_url;
92}
93
94static const X509V3_EXT_METHOD x509v3_ext_netscape_revocation_url = {
95 .ext_nid = NID_netscape_revocation_url,
96 .ext_flags = 0,
97 .it = &ASN1_IA5STRING_it,
98 .ext_new = NULL,
99 .ext_free = NULL,
100 .d2i = NULL,
101 .i2d = NULL,
102 .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING,
103 .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING,
104 .i2v = NULL,
105 .v2i = NULL,
106 .i2r = NULL,
107 .r2i = NULL,
108 .usr_data = NULL,
109};
110
111const X509V3_EXT_METHOD *
112x509v3_ext_method_netscape_revocation_url(void)
113{
114 return &x509v3_ext_netscape_revocation_url;
115}
116
117static const X509V3_EXT_METHOD x509v3_ext_netscape_ca_revocation_url = {
118 .ext_nid = NID_netscape_ca_revocation_url,
119 .ext_flags = 0,
120 .it = &ASN1_IA5STRING_it,
121 .ext_new = NULL,
122 .ext_free = NULL,
123 .d2i = NULL,
124 .i2d = NULL,
125 .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING,
126 .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING,
127 .i2v = NULL,
128 .v2i = NULL,
129 .i2r = NULL,
130 .r2i = NULL,
131 .usr_data = NULL,
132};
133
134const X509V3_EXT_METHOD *
135x509v3_ext_method_netscape_ca_revocation_url(void)
136{
137 return &x509v3_ext_netscape_ca_revocation_url;
138}
139
140static const X509V3_EXT_METHOD x509v3_ext_netscape_renewal_url = {
141 .ext_nid = NID_netscape_renewal_url,
142 .ext_flags = 0,
143 .it = &ASN1_IA5STRING_it,
144 .ext_new = NULL,
145 .ext_free = NULL,
146 .d2i = NULL,
147 .i2d = NULL,
148 .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING,
149 .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING,
150 .i2v = NULL,
151 .v2i = NULL,
152 .i2r = NULL,
153 .r2i = NULL,
154 .usr_data = NULL,
155};
156
157const X509V3_EXT_METHOD *
158x509v3_ext_method_netscape_renewal_url(void)
159{
160 return &x509v3_ext_netscape_renewal_url;
161}
162
163static const X509V3_EXT_METHOD x509v3_ext_netscape_ca_policy_url = {
164 .ext_nid = NID_netscape_ca_policy_url,
165 .ext_flags = 0,
166 .it = &ASN1_IA5STRING_it,
167 .ext_new = NULL,
168 .ext_free = NULL,
169 .d2i = NULL,
170 .i2d = NULL,
171 .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING,
172 .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING,
173 .i2v = NULL,
174 .v2i = NULL,
175 .i2r = NULL,
176 .r2i = NULL,
177 .usr_data = NULL,
178};
179
180const X509V3_EXT_METHOD *
181x509v3_ext_method_netscape_ca_policy_url(void)
182{
183 return &x509v3_ext_netscape_ca_policy_url;
184}
185
186static const X509V3_EXT_METHOD x509v3_ext_netscape_ssl_server_name = {
187 .ext_nid = NID_netscape_ssl_server_name,
188 .ext_flags = 0,
189 .it = &ASN1_IA5STRING_it,
190 .ext_new = NULL,
191 .ext_free = NULL,
192 .d2i = NULL,
193 .i2d = NULL,
194 .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING,
195 .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING,
196 .i2v = NULL,
197 .v2i = NULL,
198 .i2r = NULL,
199 .r2i = NULL,
200 .usr_data = NULL,
201};
202
203const X509V3_EXT_METHOD *
204x509v3_ext_method_netscape_ssl_server_name(void)
205{
206 return &x509v3_ext_netscape_ssl_server_name;
207}
208
209static const X509V3_EXT_METHOD x509v3_ext_netscape_comment = {
210 .ext_nid = NID_netscape_comment,
211 .ext_flags = 0,
212 .it = &ASN1_IA5STRING_it,
213 .ext_new = NULL,
214 .ext_free = NULL,
215 .d2i = NULL,
216 .i2d = NULL,
217 .i2s = (X509V3_EXT_I2S)i2s_ASN1_IA5STRING,
218 .s2i = (X509V3_EXT_S2I)s2i_ASN1_IA5STRING,
219 .i2v = NULL,
220 .v2i = NULL,
221 .i2r = NULL,
222 .r2i = NULL,
223 .usr_data = NULL,
224};
225
226const X509V3_EXT_METHOD *
227x509v3_ext_method_netscape_comment(void)
228{
229 return &x509v3_ext_netscape_comment;
230}
231
232static char *
233i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5)
234{
235 char *tmp;
236
237 if (!ia5 || !ia5->length)
238 return NULL;
239 if (!(tmp = malloc(ia5->length + 1))) {
240 X509V3error(ERR_R_MALLOC_FAILURE);
241 return NULL;
242 }
243 memcpy(tmp, ia5->data, ia5->length);
244 tmp[ia5->length] = 0;
245 return tmp;
246}
247
248static ASN1_IA5STRING *
249s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str)
250{
251 ASN1_IA5STRING *ia5;
252 if (!str) {
253 X509V3error(X509V3_R_INVALID_NULL_ARGUMENT);
254 return NULL;
255 }
256 if (!(ia5 = ASN1_IA5STRING_new()))
257 goto err;
258 if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str,
259 strlen(str))) {
260 ASN1_IA5STRING_free(ia5);
261 goto err;
262 }
263 return ia5;
264
265err:
266 X509V3error(ERR_R_MALLOC_FAILURE);
267 return NULL;
268}
diff --git a/src/lib/libcrypto/x509/x509_info.c b/src/lib/libcrypto/x509/x509_info.c
deleted file mode 100644
index d1de346ee6..0000000000
--- a/src/lib/libcrypto/x509/x509_info.c
+++ /dev/null
@@ -1,331 +0,0 @@
1/* $OpenBSD: x509_info.c,v 1.5 2024/07/13 15:08:58 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
64#include <openssl/conf.h>
65#include <openssl/err.h>
66#include <openssl/x509v3.h>
67
68static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
69 X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo,
70 STACK_OF(CONF_VALUE) *ret);
71static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(
72 X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
73
74static const X509V3_EXT_METHOD x509v3_ext_info_access = {
75 .ext_nid = NID_info_access,
76 .ext_flags = X509V3_EXT_MULTILINE,
77 .it = &AUTHORITY_INFO_ACCESS_it,
78 .ext_new = NULL,
79 .ext_free = NULL,
80 .d2i = NULL,
81 .i2d = NULL,
82 .i2s = NULL,
83 .s2i = NULL,
84 .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
85 .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
86 .i2r = NULL,
87 .r2i = NULL,
88 .usr_data = NULL,
89};
90
91const X509V3_EXT_METHOD *
92x509v3_ext_method_info_access(void)
93{
94 return &x509v3_ext_info_access;
95}
96
97static const X509V3_EXT_METHOD x509v3_ext_sinfo_access = {
98 .ext_nid = NID_sinfo_access,
99 .ext_flags = X509V3_EXT_MULTILINE,
100 .it = &AUTHORITY_INFO_ACCESS_it,
101 .ext_new = NULL,
102 .ext_free = NULL,
103 .d2i = NULL,
104 .i2d = NULL,
105 .i2s = NULL,
106 .s2i = NULL,
107 .i2v = (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
108 .v2i = (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
109 .i2r = NULL,
110 .r2i = NULL,
111 .usr_data = NULL,
112};
113
114const X509V3_EXT_METHOD *
115x509v3_ext_method_sinfo_access(void)
116{
117 return &x509v3_ext_sinfo_access;
118}
119
120static const ASN1_TEMPLATE ACCESS_DESCRIPTION_seq_tt[] = {
121 {
122 .flags = 0,
123 .tag = 0,
124 .offset = offsetof(ACCESS_DESCRIPTION, method),
125 .field_name = "method",
126 .item = &ASN1_OBJECT_it,
127 },
128 {
129 .flags = 0,
130 .tag = 0,
131 .offset = offsetof(ACCESS_DESCRIPTION, location),
132 .field_name = "location",
133 .item = &GENERAL_NAME_it,
134 },
135};
136
137const ASN1_ITEM ACCESS_DESCRIPTION_it = {
138 .itype = ASN1_ITYPE_SEQUENCE,
139 .utype = V_ASN1_SEQUENCE,
140 .templates = ACCESS_DESCRIPTION_seq_tt,
141 .tcount = sizeof(ACCESS_DESCRIPTION_seq_tt) / sizeof(ASN1_TEMPLATE),
142 .funcs = NULL,
143 .size = sizeof(ACCESS_DESCRIPTION),
144 .sname = "ACCESS_DESCRIPTION",
145};
146LCRYPTO_ALIAS(ACCESS_DESCRIPTION_it);
147
148
149ACCESS_DESCRIPTION *
150d2i_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION **a, const unsigned char **in, long len)
151{
152 return (ACCESS_DESCRIPTION *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
153 &ACCESS_DESCRIPTION_it);
154}
155LCRYPTO_ALIAS(d2i_ACCESS_DESCRIPTION);
156
157int
158i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out)
159{
160 return ASN1_item_i2d((ASN1_VALUE *)a, out, &ACCESS_DESCRIPTION_it);
161}
162LCRYPTO_ALIAS(i2d_ACCESS_DESCRIPTION);
163
164ACCESS_DESCRIPTION *
165ACCESS_DESCRIPTION_new(void)
166{
167 return (ACCESS_DESCRIPTION *)ASN1_item_new(&ACCESS_DESCRIPTION_it);
168}
169LCRYPTO_ALIAS(ACCESS_DESCRIPTION_new);
170
171void
172ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a)
173{
174 ASN1_item_free((ASN1_VALUE *)a, &ACCESS_DESCRIPTION_it);
175}
176LCRYPTO_ALIAS(ACCESS_DESCRIPTION_free);
177
178static const ASN1_TEMPLATE AUTHORITY_INFO_ACCESS_item_tt = {
179 .flags = ASN1_TFLG_SEQUENCE_OF,
180 .tag = 0,
181 .offset = 0,
182 .field_name = "GeneralNames",
183 .item = &ACCESS_DESCRIPTION_it,
184};
185
186const ASN1_ITEM AUTHORITY_INFO_ACCESS_it = {
187 .itype = ASN1_ITYPE_PRIMITIVE,
188 .utype = -1,
189 .templates = &AUTHORITY_INFO_ACCESS_item_tt,
190 .tcount = 0,
191 .funcs = NULL,
192 .size = 0,
193 .sname = "AUTHORITY_INFO_ACCESS",
194};
195LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_it);
196
197
198AUTHORITY_INFO_ACCESS *
199d2i_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS **a, const unsigned char **in, long len)
200{
201 return (AUTHORITY_INFO_ACCESS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
202 &AUTHORITY_INFO_ACCESS_it);
203}
204LCRYPTO_ALIAS(d2i_AUTHORITY_INFO_ACCESS);
205
206int
207i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out)
208{
209 return ASN1_item_i2d((ASN1_VALUE *)a, out, &AUTHORITY_INFO_ACCESS_it);
210}
211LCRYPTO_ALIAS(i2d_AUTHORITY_INFO_ACCESS);
212
213AUTHORITY_INFO_ACCESS *
214AUTHORITY_INFO_ACCESS_new(void)
215{
216 return (AUTHORITY_INFO_ACCESS *)ASN1_item_new(&AUTHORITY_INFO_ACCESS_it);
217}
218LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_new);
219
220void
221AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a)
222{
223 ASN1_item_free((ASN1_VALUE *)a, &AUTHORITY_INFO_ACCESS_it);
224}
225LCRYPTO_ALIAS(AUTHORITY_INFO_ACCESS_free);
226
227static STACK_OF(CONF_VALUE) *
228i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method,
229 AUTHORITY_INFO_ACCESS *ainfo, STACK_OF(CONF_VALUE) *ret)
230{
231 ACCESS_DESCRIPTION *desc;
232 CONF_VALUE *vtmp;
233 STACK_OF(CONF_VALUE) *free_ret = NULL;
234 char objtmp[80], *ntmp;
235 int i;
236
237 if (ret == NULL) {
238 if ((free_ret = ret = sk_CONF_VALUE_new_null()) == NULL)
239 return NULL;
240 }
241
242 for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
243 if ((desc = sk_ACCESS_DESCRIPTION_value(ainfo, i)) == NULL)
244 goto err;
245 if ((ret = i2v_GENERAL_NAME(method, desc->location,
246 ret)) == NULL)
247 goto err;
248 if ((vtmp = sk_CONF_VALUE_value(ret, i)) == NULL)
249 goto err;
250 if (!i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method))
251 goto err;
252 if (asprintf(&ntmp, "%s - %s", objtmp, vtmp->name) == -1) {
253 ntmp = NULL;
254 X509V3error(ERR_R_MALLOC_FAILURE);
255 goto err;
256 }
257 free(vtmp->name);
258 vtmp->name = ntmp;
259 }
260
261 return ret;
262
263 err:
264 sk_CONF_VALUE_pop_free(free_ret, X509V3_conf_free);
265
266 return NULL;
267}
268
269static AUTHORITY_INFO_ACCESS *
270v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
271 STACK_OF(CONF_VALUE) *nval)
272{
273 AUTHORITY_INFO_ACCESS *ainfo = NULL;
274 CONF_VALUE *cnf, ctmp;
275 ACCESS_DESCRIPTION *acc;
276 int i, objlen;
277 char *objtmp, *ptmp;
278
279 if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
280 X509V3error(ERR_R_MALLOC_FAILURE);
281 return NULL;
282 }
283 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
284 cnf = sk_CONF_VALUE_value(nval, i);
285 if ((acc = ACCESS_DESCRIPTION_new()) == NULL) {
286 X509V3error(ERR_R_MALLOC_FAILURE);
287 goto err;
288 }
289 if (sk_ACCESS_DESCRIPTION_push(ainfo, acc) == 0) {
290 ACCESS_DESCRIPTION_free(acc);
291 X509V3error(ERR_R_MALLOC_FAILURE);
292 goto err;
293 }
294 ptmp = strchr(cnf->name, ';');
295 if (!ptmp) {
296 X509V3error(X509V3_R_INVALID_SYNTAX);
297 goto err;
298 }
299 objlen = ptmp - cnf->name;
300 ctmp.name = ptmp + 1;
301 ctmp.value = cnf->value;
302 if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
303 goto err;
304 if (!(objtmp = malloc(objlen + 1))) {
305 X509V3error(ERR_R_MALLOC_FAILURE);
306 goto err;
307 }
308 strlcpy(objtmp, cnf->name, objlen + 1);
309 acc->method = OBJ_txt2obj(objtmp, 0);
310 if (!acc->method) {
311 X509V3error(X509V3_R_BAD_OBJECT);
312 ERR_asprintf_error_data("value=%s", objtmp);
313 free(objtmp);
314 goto err;
315 }
316 free(objtmp);
317 }
318 return ainfo;
319
320err:
321 sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
322 return NULL;
323}
324
325int
326i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION* a)
327{
328 i2a_ASN1_OBJECT(bp, a->method);
329 return 2;
330}
331LCRYPTO_ALIAS(i2a_ACCESS_DESCRIPTION);
diff --git a/src/lib/libcrypto/x509/x509_int.c b/src/lib/libcrypto/x509/x509_int.c
deleted file mode 100644
index 2236bfe4c4..0000000000
--- a/src/lib/libcrypto/x509/x509_int.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/* $OpenBSD: x509_int.c,v 1.2 2024/07/13 15:08:58 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-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 */
58
59#include <stdio.h>
60
61#include <openssl/x509v3.h>
62
63static const X509V3_EXT_METHOD x509v3_ext_crl_number = {
64 .ext_nid = NID_crl_number,
65 .ext_flags = 0,
66 .it = &ASN1_INTEGER_it,
67 .ext_new = NULL,
68 .ext_free = NULL,
69 .d2i = NULL,
70 .i2d = NULL,
71 .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
72 .s2i = NULL,
73 .i2v = NULL,
74 .v2i = NULL,
75 .i2r = NULL,
76 .r2i = NULL,
77 .usr_data = NULL,
78};
79
80const X509V3_EXT_METHOD *
81x509v3_ext_method_crl_number(void)
82{
83 return &x509v3_ext_crl_number;
84}
85
86static const X509V3_EXT_METHOD x509v3_ext_delta_crl = {
87 .ext_nid = NID_delta_crl,
88 .ext_flags = 0,
89 .it = &ASN1_INTEGER_it,
90 .ext_new = NULL,
91 .ext_free = NULL,
92 .d2i = NULL,
93 .i2d = NULL,
94 .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
95 .s2i = NULL,
96 .i2v = NULL,
97 .v2i = NULL,
98 .i2r = NULL,
99 .r2i = NULL,
100 .usr_data = NULL,
101};
102
103const X509V3_EXT_METHOD *
104x509v3_ext_method_delta_crl(void)
105{
106 return &x509v3_ext_delta_crl;
107}
108
109static void *
110s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, char *value)
111{
112 return s2i_ASN1_INTEGER(meth, value);
113}
114
115static const X509V3_EXT_METHOD x509v3_ext_inhibit_any_policy = {
116 .ext_nid = NID_inhibit_any_policy,
117 .ext_flags = 0,
118 .it = &ASN1_INTEGER_it,
119 .ext_new = NULL,
120 .ext_free = NULL,
121 .d2i = NULL,
122 .i2d = NULL,
123 .i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
124 .s2i = (X509V3_EXT_S2I)s2i_asn1_int,
125 .i2v = NULL,
126 .v2i = NULL,
127 .i2r = NULL,
128 .r2i = NULL,
129 .usr_data = NULL,
130};
131
132const X509V3_EXT_METHOD *
133x509v3_ext_method_inhibit_any_policy(void)
134{
135 return &x509v3_ext_inhibit_any_policy;
136}
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h
deleted file mode 100644
index 9b9980ece5..0000000000
--- a/src/lib/libcrypto/x509/x509_internal.h
+++ /dev/null
@@ -1,141 +0,0 @@
1/* $OpenBSD: x509_internal.h,v 1.28 2024/05/19 07:12:50 jsg Exp $ */
2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17#ifndef HEADER_X509_INTERNAL_H
18#define HEADER_X509_INTERNAL_H
19
20/* Internal use only, not public API */
21#include <netinet/in.h>
22
23#include "bytestring.h"
24#include "x509_local.h"
25#include "x509_verify.h"
26
27/* Hard limits on structure size and number of signature checks. */
28#define X509_VERIFY_MAX_CHAINS 8 /* Max validated chains */
29#define X509_VERIFY_MAX_CHAIN_CERTS 32 /* Max depth of a chain */
30#define X509_VERIFY_MAX_SIGCHECKS 256 /* Max signature checks */
31
32/*
33 * Limit the number of names and constraints we will check in a chain
34 * to avoid a hostile input DOS
35 */
36#define X509_VERIFY_MAX_CHAIN_NAMES 512
37#define X509_VERIFY_MAX_CHAIN_CONSTRAINTS 512
38
39/*
40 * Hold the parsed and validated result of names from a certificate.
41 * these typically come from a GENERALNAME, but we store the parsed
42 * and validated results, not the ASN1 bytes.
43 */
44struct x509_constraints_name {
45 int type; /* GEN_* types from GENERAL_NAME */
46 char *name; /* Name to check */
47 char *local; /* holds the local part of GEN_EMAIL */
48 uint8_t *der; /* DER encoded value or NULL*/
49 size_t der_len;
50 int af; /* INET and INET6 are supported */
51 uint8_t address[32]; /* Must hold ipv6 + mask */
52};
53
54struct x509_constraints_names {
55 struct x509_constraints_name **names;
56 size_t names_count;
57 size_t names_len;
58 size_t names_max;
59};
60
61struct x509_verify_chain {
62 STACK_OF(X509) *certs; /* Kept in chain order, includes leaf */
63 int *cert_errors; /* Verify error for each cert in chain. */
64 struct x509_constraints_names *names; /* All names from all certs */
65};
66
67struct x509_verify_ctx {
68 X509_STORE_CTX *xsc;
69 struct x509_verify_chain **chains; /* Validated chains */
70 STACK_OF(X509) *saved_error_chain;
71 int saved_error;
72 int saved_error_depth;
73 size_t chains_count;
74 STACK_OF(X509) *roots; /* Trusted roots for this validation */
75 STACK_OF(X509) *intermediates; /* Intermediates provided by peer */
76 time_t *check_time; /* Time for validity checks */
77 int purpose; /* Cert purpose we are validating */
78 size_t max_chains; /* Max chains to return */
79 size_t max_depth; /* Max chain depth for validation */
80 size_t max_sigs; /* Max number of signature checks */
81 size_t sig_checks; /* Number of signature checks done */
82 size_t error_depth; /* Depth of last error seen */
83 int error; /* Last error seen */
84};
85
86int ASN1_time_tm_clamp_notafter(struct tm *tm);
87
88__BEGIN_HIDDEN_DECLS
89
90int x509_vfy_check_id(X509_STORE_CTX *ctx);
91int x509_vfy_check_revocation(X509_STORE_CTX *ctx);
92int x509_vfy_check_policy(X509_STORE_CTX *ctx);
93int x509_vfy_check_trust(X509_STORE_CTX *ctx);
94int x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx);
95int x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx);
96int x509v3_cache_extensions(X509 *x);
97X509 *x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x);
98
99int x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter,
100 time_t *out);
101
102struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc);
103
104void x509_constraints_name_clear(struct x509_constraints_name *name);
105void x509_constraints_name_free(struct x509_constraints_name *name);
106int x509_constraints_names_add(struct x509_constraints_names *names,
107 struct x509_constraints_name *name);
108struct x509_constraints_names *x509_constraints_names_dup(
109 struct x509_constraints_names *names);
110void x509_constraints_names_clear(struct x509_constraints_names *names);
111struct x509_constraints_names *x509_constraints_names_new(size_t names_max);
112int x509_constraints_general_to_bytes(GENERAL_NAME *name, uint8_t **bytes,
113 size_t *len);
114void x509_constraints_names_free(struct x509_constraints_names *names);
115int x509_constraints_valid_host(CBS *cbs, int permit_ip);
116int x509_constraints_valid_sandns(CBS *cbs);
117int x509_constraints_domain(char *domain, size_t dlen, char *constraint,
118 size_t len);
119int x509_constraints_parse_mailbox(CBS *candidate,
120 struct x509_constraints_name *name);
121int x509_constraints_valid_domain_constraint(CBS *cbs);
122int x509_constraints_uri_host(uint8_t *uri, size_t len, char **hostp);
123int x509_constraints_uri(uint8_t *uri, size_t ulen, uint8_t *constraint,
124 size_t len, int *error);
125int x509_constraints_extract_names(struct x509_constraints_names *names,
126 X509 *cert, int include_cn, int *error);
127int x509_constraints_extract_constraints(X509 *cert,
128 struct x509_constraints_names *permitted,
129 struct x509_constraints_names *excluded, int *error);
130int x509_constraints_validate(GENERAL_NAME *constraint,
131 struct x509_constraints_name **out_name, int *error);
132int x509_constraints_check(struct x509_constraints_names *names,
133 struct x509_constraints_names *permitted,
134 struct x509_constraints_names *excluded, int *error);
135int x509_constraints_chain(STACK_OF(X509) *chain, int *error,
136 int *depth);
137int x509_vfy_check_security_level(X509_STORE_CTX *ctx);
138
139__END_HIDDEN_DECLS
140
141#endif
diff --git a/src/lib/libcrypto/x509/x509_issuer_cache.c b/src/lib/libcrypto/x509/x509_issuer_cache.c
deleted file mode 100644
index 070e85b0a9..0000000000
--- a/src/lib/libcrypto/x509/x509_issuer_cache.c
+++ /dev/null
@@ -1,193 +0,0 @@
1/* $OpenBSD: x509_issuer_cache.c,v 1.7 2023/12/30 18:26:13 tb Exp $ */
2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* x509_issuer_cache */
19
20/*
21 * The issuer cache is a cache of parent and child x509 certificate
22 * hashes with a signature validation result.
23 *
24 * Entries should only be added to the cache with a validation result
25 * from checking the public key math that "parent" signed "child".
26 *
27 * Finding an entry in the cache gets us the result of a previously
28 * performed validation of the signature of "parent" signing for the
29 * validity of "child". It allows us to skip doing the public key math
30 * when validating a certificate chain. It does not allow us to skip
31 * any other steps of validation (times, names, key usage, etc.)
32 */
33
34#include <pthread.h>
35#include <string.h>
36
37#include "x509_issuer_cache.h"
38
39static int
40x509_issuer_cmp(struct x509_issuer *x1, struct x509_issuer *x2)
41{
42 int pcmp;
43 if ((pcmp = memcmp(x1->parent_md, x2->parent_md, EVP_MAX_MD_SIZE)) != 0)
44 return pcmp;
45 return memcmp(x1->child_md, x2->child_md, EVP_MAX_MD_SIZE);
46}
47
48static size_t x509_issuer_cache_count;
49static size_t x509_issuer_cache_max = X509_ISSUER_CACHE_MAX;
50static RB_HEAD(x509_issuer_tree, x509_issuer) x509_issuer_cache =
51 RB_INITIALIZER(&x509_issuer_cache);
52static TAILQ_HEAD(lruqueue, x509_issuer) x509_issuer_lru =
53 TAILQ_HEAD_INITIALIZER(x509_issuer_lru);
54static pthread_mutex_t x509_issuer_tree_mutex = PTHREAD_MUTEX_INITIALIZER;
55
56RB_PROTOTYPE(x509_issuer_tree, x509_issuer, entry, x509_issuer_cmp);
57RB_GENERATE(x509_issuer_tree, x509_issuer, entry, x509_issuer_cmp);
58
59/*
60 * Set the maximum number of cached entries. On additions to the cache
61 * the least recently used entries will be discarded so that the cache
62 * stays under the maximum number of entries. Setting a maximum of 0
63 * disables the cache.
64 */
65int
66x509_issuer_cache_set_max(size_t max)
67{
68 if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0)
69 return 0;
70 x509_issuer_cache_max = max;
71 (void) pthread_mutex_unlock(&x509_issuer_tree_mutex);
72
73 return 1;
74}
75
76/*
77 * Free the oldest entry in the issuer cache. Returns 1
78 * if an entry was successfully freed, 0 otherwise. Must
79 * be called with x509_issuer_tree_mutex held.
80 */
81static void
82x509_issuer_cache_free_oldest(void)
83{
84 struct x509_issuer *old;
85
86 if (x509_issuer_cache_count == 0)
87 return;
88 old = TAILQ_LAST(&x509_issuer_lru, lruqueue);
89 TAILQ_REMOVE(&x509_issuer_lru, old, queue);
90 RB_REMOVE(x509_issuer_tree, &x509_issuer_cache, old);
91 free(old->parent_md);
92 free(old->child_md);
93 free(old);
94 x509_issuer_cache_count--;
95}
96
97/*
98 * Free the entire issuer cache, discarding all entries.
99 */
100void
101x509_issuer_cache_free(void)
102{
103 if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0)
104 return;
105 while (x509_issuer_cache_count > 0)
106 x509_issuer_cache_free_oldest();
107 (void) pthread_mutex_unlock(&x509_issuer_tree_mutex);
108}
109
110/*
111 * Find a previous result of checking if parent signed child
112 *
113 * Returns:
114 * -1 : No entry exists in the cache. signature must be checked.
115 * 0 : The signature of parent signing child is invalid.
116 * 1 : The signature of parent signing child is valid.
117 */
118int
119x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md)
120{
121 struct x509_issuer candidate, *found;
122 int ret = -1;
123
124 memset(&candidate, 0, sizeof(candidate));
125 candidate.parent_md = parent_md;
126 candidate.child_md = child_md;
127
128 if (x509_issuer_cache_max == 0)
129 return -1;
130
131 if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0)
132 return -1;
133 if ((found = RB_FIND(x509_issuer_tree, &x509_issuer_cache,
134 &candidate)) != NULL) {
135 TAILQ_REMOVE(&x509_issuer_lru, found, queue);
136 TAILQ_INSERT_HEAD(&x509_issuer_lru, found, queue);
137 ret = found->valid;
138 }
139 (void) pthread_mutex_unlock(&x509_issuer_tree_mutex);
140
141 return ret;
142}
143
144/*
145 * Attempt to add a validation result to the cache.
146 *
147 * valid must be:
148 * 0: The signature of parent signing child is invalid.
149 * 1: The signature of parent signing child is valid.
150 *
151 * Previously added entries for the same parent and child are *not* replaced.
152 */
153void
154x509_issuer_cache_add(unsigned char *parent_md, unsigned char *child_md,
155 int valid)
156{
157 struct x509_issuer *new;
158
159 if (x509_issuer_cache_max == 0)
160 return;
161 if (valid != 0 && valid != 1)
162 return;
163
164 if ((new = calloc(1, sizeof(struct x509_issuer))) == NULL)
165 return;
166 if ((new->parent_md = calloc(1, EVP_MAX_MD_SIZE)) == NULL)
167 goto err;
168 memcpy(new->parent_md, parent_md, EVP_MAX_MD_SIZE);
169 if ((new->child_md = calloc(1, EVP_MAX_MD_SIZE)) == NULL)
170 goto err;
171 memcpy(new->child_md, child_md, EVP_MAX_MD_SIZE);
172
173 new->valid = valid;
174
175 if (pthread_mutex_lock(&x509_issuer_tree_mutex) != 0)
176 goto err;
177 while (x509_issuer_cache_count >= x509_issuer_cache_max)
178 x509_issuer_cache_free_oldest();
179 if (RB_INSERT(x509_issuer_tree, &x509_issuer_cache, new) == NULL) {
180 TAILQ_INSERT_HEAD(&x509_issuer_lru, new, queue);
181 x509_issuer_cache_count++;
182 new = NULL;
183 }
184 (void) pthread_mutex_unlock(&x509_issuer_tree_mutex);
185
186 err:
187 if (new != NULL) {
188 free(new->parent_md);
189 free(new->child_md);
190 }
191 free(new);
192 return;
193}
diff --git a/src/lib/libcrypto/x509/x509_issuer_cache.h b/src/lib/libcrypto/x509/x509_issuer_cache.h
deleted file mode 100644
index 00b18be0de..0000000000
--- a/src/lib/libcrypto/x509/x509_issuer_cache.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/* $OpenBSD: x509_issuer_cache.h,v 1.3 2023/12/30 18:06:59 tb Exp $ */
2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* x509_issuer_cache */
19#ifndef HEADER_X509_ISSUER_CACHE_H
20#define HEADER_X509_ISSUER_CACHE_H
21
22#include <sys/tree.h>
23#include <sys/queue.h>
24
25#include <openssl/x509.h>
26
27__BEGIN_HIDDEN_DECLS
28
29struct x509_issuer {
30 RB_ENTRY(x509_issuer) entry;
31 TAILQ_ENTRY(x509_issuer) queue; /* LRU of entries */
32 /* parent_md and child_md must point to EVP_MAX_MD_SIZE of memory */
33 unsigned char *parent_md;
34 unsigned char *child_md;
35 int valid; /* Result of signature validation. */
36};
37
38#define X509_ISSUER_CACHE_MAX 40000 /* Approx 7.5 MB, entries 200 bytes */
39
40int x509_issuer_cache_set_max(size_t max);
41int x509_issuer_cache_find(unsigned char *parent_md, unsigned char *child_md);
42void x509_issuer_cache_add(unsigned char *parent_md, unsigned char *child_md,
43 int valid);
44void x509_issuer_cache_free(void);
45
46__END_HIDDEN_DECLS
47
48#endif
diff --git a/src/lib/libcrypto/x509/x509_lib.c b/src/lib/libcrypto/x509/x509_lib.c
deleted file mode 100644
index 6fa66ab88e..0000000000
--- a/src/lib/libcrypto/x509/x509_lib.c
+++ /dev/null
@@ -1,374 +0,0 @@
1/* $OpenBSD: x509_lib.c,v 1.24 2024/07/13 15:08:58 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58/* X509 v3 extension utilities */
59
60#include <stdio.h>
61
62#include <openssl/conf.h>
63#include <openssl/err.h>
64#include <openssl/x509v3.h>
65
66#include "x509_local.h"
67
68const X509V3_EXT_METHOD *
69X509V3_EXT_get_nid(int nid)
70{
71 switch (nid) {
72 case NID_authority_key_identifier:
73 return x509v3_ext_method_authority_key_identifier();
74 case NID_basic_constraints:
75 return x509v3_ext_method_basic_constraints();
76 case NID_certificate_issuer:
77 return x509v3_ext_method_certificate_issuer();
78 case NID_certificate_policies:
79 return x509v3_ext_method_certificate_policies();
80 case NID_crl_distribution_points:
81 return x509v3_ext_method_crl_distribution_points();
82 case NID_crl_number:
83 return x509v3_ext_method_crl_number();
84 case NID_crl_reason:
85 return x509v3_ext_method_crl_reason();
86#ifndef OPENSSL_NO_CT
87 case NID_ct_cert_scts:
88 return x509v3_ext_method_ct_cert_scts();
89 case NID_ct_precert_poison:
90 return x509v3_ext_method_ct_precert_poison();
91 case NID_ct_precert_scts:
92 return x509v3_ext_method_ct_precert_scts();
93#endif
94 case NID_delta_crl:
95 return x509v3_ext_method_delta_crl();
96 case NID_ext_key_usage:
97 return x509v3_ext_method_ext_key_usage();
98 case NID_freshest_crl:
99 return x509v3_ext_method_freshest_crl();
100#ifndef OPENSSL_NO_OCSP
101 case NID_hold_instruction_code:
102 return x509v3_ext_method_hold_instruction_code();
103 case NID_id_pkix_OCSP_CrlID:
104 return x509v3_ext_method_id_pkix_OCSP_CrlID();
105 case NID_id_pkix_OCSP_Nonce:
106 return x509v3_ext_method_id_pkix_OCSP_Nonce();
107 case NID_id_pkix_OCSP_acceptableResponses:
108 return x509v3_ext_method_id_pkix_OCSP_acceptableResponses();
109 case NID_id_pkix_OCSP_archiveCutoff:
110 return x509v3_ext_method_id_pkix_OCSP_archiveCutoff();
111 case NID_id_pkix_OCSP_serviceLocator:
112 return x509v3_ext_method_id_pkix_OCSP_serviceLocator();
113#endif
114 case NID_info_access:
115 return x509v3_ext_method_info_access();
116 case NID_inhibit_any_policy:
117 return x509v3_ext_method_inhibit_any_policy();
118 case NID_invalidity_date:
119 return x509v3_ext_method_invalidity_date();
120 case NID_issuer_alt_name:
121 return x509v3_ext_method_issuer_alt_name();
122 case NID_issuing_distribution_point:
123 return x509v3_ext_method_issuing_distribution_point();
124 case NID_key_usage:
125 return x509v3_ext_method_key_usage();
126 case NID_name_constraints:
127 return x509v3_ext_method_name_constraints();
128 case NID_netscape_base_url:
129 return x509v3_ext_method_netscape_base_url();
130 case NID_netscape_ca_policy_url:
131 return x509v3_ext_method_netscape_ca_policy_url();
132 case NID_netscape_ca_revocation_url:
133 return x509v3_ext_method_netscape_ca_revocation_url();
134 case NID_netscape_cert_type:
135 return x509v3_ext_method_netscape_cert_type();
136 case NID_netscape_comment:
137 return x509v3_ext_method_netscape_comment();
138 case NID_netscape_renewal_url:
139 return x509v3_ext_method_netscape_renewal_url();
140 case NID_netscape_revocation_url:
141 return x509v3_ext_method_netscape_revocation_url();
142 case NID_netscape_ssl_server_name:
143 return x509v3_ext_method_netscape_ssl_server_name();
144 case NID_policy_constraints:
145 return x509v3_ext_method_policy_constraints();
146 case NID_policy_mappings:
147 return x509v3_ext_method_policy_mappings();
148 case NID_private_key_usage_period:
149 return x509v3_ext_method_private_key_usage_period();
150#ifndef OPENSSL_NO_RFC3779
151 case NID_sbgp_ipAddrBlock:
152 return x509v3_ext_method_sbgp_ipAddrBlock();
153 case NID_sbgp_autonomousSysNum:
154 return x509v3_ext_method_sbgp_autonomousSysNum();
155#endif
156 case NID_sinfo_access:
157 return x509v3_ext_method_sinfo_access();
158 case NID_subject_alt_name:
159 return x509v3_ext_method_subject_alt_name();
160 case NID_subject_key_identifier:
161 return x509v3_ext_method_subject_key_identifier();
162 default:
163 return NULL;
164 }
165};
166LCRYPTO_ALIAS(X509V3_EXT_get_nid);
167
168const X509V3_EXT_METHOD *
169X509V3_EXT_get(X509_EXTENSION *ext)
170{
171 int nid;
172
173 if ((nid = OBJ_obj2nid(ext->object)) == NID_undef)
174 return NULL;
175 return X509V3_EXT_get_nid(nid);
176}
177LCRYPTO_ALIAS(X509V3_EXT_get);
178
179/* Return an extension internal structure */
180
181void *
182X509V3_EXT_d2i(X509_EXTENSION *ext)
183{
184 const X509V3_EXT_METHOD *method;
185 const unsigned char *p;
186
187 if ((method = X509V3_EXT_get(ext)) == NULL)
188 return NULL;
189 p = ext->value->data;
190 if (method->it != NULL)
191 return ASN1_item_d2i(NULL, &p, ext->value->length, method->it);
192 return method->d2i(NULL, &p, ext->value->length);
193}
194LCRYPTO_ALIAS(X509V3_EXT_d2i);
195
196/*
197 * This API is only safe to call with known nid, crit != NULL and idx == NULL.
198 * On NULL return, crit acts as a failure indicator: crit == -1 means an
199 * extension of type nid was not present, crit != -1 is fatal: crit == -2
200 * means multiple extensions of type nid are present; if crit is 0 or 1, this
201 * implies the extension was found but could not be decoded.
202 */
203
204void *
205X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x509_exts, int nid, int *crit,
206 int *idx)
207{
208 X509_EXTENSION *ext;
209 int lastpos = idx == NULL ? -1 : *idx;
210
211 if (crit != NULL)
212 *crit = -1;
213 if (idx != NULL)
214 *idx = -1;
215
216 /*
217 * Nothing to do if no extensions, unknown nid, or missing extension.
218 */
219
220 if (x509_exts == NULL)
221 return NULL;
222 if ((lastpos = X509v3_get_ext_by_NID(x509_exts, nid, lastpos)) < 0)
223 return NULL;
224 if ((ext = X509v3_get_ext(x509_exts, lastpos)) == NULL)
225 return NULL;
226
227 /*
228 * API madness. Only check for a second extension of type nid if
229 * idx == NULL. Indicate this by setting *crit to -2. If idx != NULL,
230 * don't care and set *idx to the index of the first extension found.
231 */
232
233 if (idx == NULL && X509v3_get_ext_by_NID(x509_exts, nid, lastpos) > 0) {
234 if (crit != NULL)
235 *crit = -2;
236 return NULL;
237 }
238
239 /*
240 * Another beautiful API detail: *crit will be set to 0 or 1, so if the
241 * extension fails to decode, we can deduce this from return value NULL
242 * and crit != -1.
243 */
244
245 if (crit != NULL)
246 *crit = X509_EXTENSION_get_critical(ext);
247 if (idx != NULL)
248 *idx = lastpos;
249
250 return X509V3_EXT_d2i(ext);
251}
252LCRYPTO_ALIAS(X509V3_get_d2i);
253
254int
255X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x509_exts, int nid, void *value,
256 int crit, unsigned long flags)
257{
258 STACK_OF(X509_EXTENSION) *exts = *x509_exts;
259 X509_EXTENSION *ext = NULL;
260 X509_EXTENSION *existing;
261 int extidx;
262 int errcode = 0;
263 int ret = 0;
264
265 /* See if the extension already exists. */
266 extidx = X509v3_get_ext_by_NID(*x509_exts, nid, -1);
267
268 switch (flags & X509V3_ADD_OP_MASK) {
269 case X509V3_ADD_DEFAULT:
270 /* If the extension exists, adding another one is an error. */
271 if (extidx >= 0) {
272 errcode = X509V3_R_EXTENSION_EXISTS;
273 goto err;
274 }
275 break;
276 case X509V3_ADD_APPEND:
277 /*
278 * XXX - Total misfeature. If the extension exists, appending
279 * another one will invalidate the certificate. Unfortunately
280 * things use this, in particular Viktor's DANE code.
281 */
282 /* Pretend the extension didn't exist and append the new one. */
283 extidx = -1;
284 break;
285 case X509V3_ADD_REPLACE:
286 /* Replace existing extension, otherwise append the new one. */
287 break;
288 case X509V3_ADD_REPLACE_EXISTING:
289 /* Can't replace a non-existent extension. */
290 if (extidx < 0) {
291 errcode = X509V3_R_EXTENSION_NOT_FOUND;
292 goto err;
293 }
294 break;
295 case X509V3_ADD_KEEP_EXISTING:
296 /* If the extension exists, there's nothing to do. */
297 if (extidx >= 0)
298 goto done;
299 break;
300 case X509V3_ADD_DELETE:
301 /* Can't delete a non-existent extension. */
302 if (extidx < 0) {
303 errcode = X509V3_R_EXTENSION_NOT_FOUND;
304 goto err;
305 }
306 if ((existing = sk_X509_EXTENSION_delete(*x509_exts,
307 extidx)) == NULL) {
308 ret = -1;
309 goto err;
310 }
311 X509_EXTENSION_free(existing);
312 existing = NULL;
313 goto done;
314 default:
315 errcode = X509V3_R_UNSUPPORTED_OPTION; /* XXX */
316 ret = -1;
317 goto err;
318 }
319
320 if ((ext = X509V3_EXT_i2d(nid, crit, value)) == NULL) {
321 X509V3error(X509V3_R_ERROR_CREATING_EXTENSION);
322 goto err;
323 }
324
325 /* From here, errors are fatal. */
326 ret = -1;
327
328 /* If extension exists, replace it. */
329 if (extidx >= 0) {
330 existing = sk_X509_EXTENSION_value(*x509_exts, extidx);
331 X509_EXTENSION_free(existing);
332 existing = NULL;
333 if (sk_X509_EXTENSION_set(*x509_exts, extidx, ext) == NULL) {
334 /*
335 * XXX - Can't happen. If it did happen, |existing| is
336 * now a freed pointer. Nothing we can do here.
337 */
338 goto err;
339 }
340 goto done;
341 }
342
343 if (exts == NULL)
344 exts = sk_X509_EXTENSION_new_null();
345 if (exts == NULL)
346 goto err;
347
348 if (!sk_X509_EXTENSION_push(exts, ext))
349 goto err;
350 ext = NULL;
351
352 *x509_exts = exts;
353
354 done:
355 return 1;
356
357 err:
358 if ((flags & X509V3_ADD_SILENT) == 0 && errcode != 0)
359 X509V3error(errcode);
360
361 if (exts != *x509_exts)
362 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
363 X509_EXTENSION_free(ext);
364
365 return ret;
366}
367LCRYPTO_ALIAS(X509V3_add1_i2d);
368
369int
370X509V3_add_standard_extensions(void)
371{
372 return 1;
373}
374LCRYPTO_ALIAS(X509V3_add_standard_extensions);
diff --git a/src/lib/libcrypto/x509/x509_local.h b/src/lib/libcrypto/x509/x509_local.h
deleted file mode 100644
index 796a2ee718..0000000000
--- a/src/lib/libcrypto/x509/x509_local.h
+++ /dev/null
@@ -1,503 +0,0 @@
1/* $OpenBSD: x509_local.h,v 1.38 2025/03/06 07:20:01 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2013.
4 */
5/* ====================================================================
6 * Copyright (c) 2013 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 */
58
59#ifndef HEADER_X509_LOCAL_H
60#define HEADER_X509_LOCAL_H
61
62#include <openssl/x509v3.h>
63
64#include "bytestring.h"
65
66__BEGIN_HIDDEN_DECLS
67
68#define TS_HASH_EVP EVP_sha1()
69#define TS_HASH_LEN SHA_DIGEST_LENGTH
70
71#define X509_CERT_HASH_EVP EVP_sha512()
72#define X509_CERT_HASH_LEN SHA512_DIGEST_LENGTH
73#define X509_CRL_HASH_EVP EVP_sha512()
74#define X509_CRL_HASH_LEN SHA512_DIGEST_LENGTH
75
76#define X509_TRUST_ACCEPT_ALL -1
77
78/* check_trust return codes */
79#define X509_TRUST_TRUSTED 1
80#define X509_TRUST_REJECTED 2
81#define X509_TRUST_UNTRUSTED 3
82
83int X509_check_trust(X509 *x, int id, int flags);
84
85struct X509_val_st {
86 ASN1_TIME *notBefore;
87 ASN1_TIME *notAfter;
88} /* X509_VAL */;
89
90struct X509_pubkey_st {
91 X509_ALGOR *algor;
92 ASN1_BIT_STRING *public_key;
93 EVP_PKEY *pkey;
94};
95
96struct X509_sig_st {
97 X509_ALGOR *algor;
98 ASN1_OCTET_STRING *digest;
99} /* X509_SIG */;
100
101struct X509_name_entry_st {
102 ASN1_OBJECT *object;
103 ASN1_STRING *value;
104 int set;
105 int size; /* temp variable */
106} /* X509_NAME_ENTRY */;
107
108/* we always keep X509_NAMEs in 2 forms. */
109struct X509_name_st {
110 STACK_OF(X509_NAME_ENTRY) *entries;
111 int modified; /* true if 'bytes' needs to be built */
112#ifndef OPENSSL_NO_BUFFER
113 BUF_MEM *bytes;
114#else
115 char *bytes;
116#endif
117/* unsigned long hash; Keep the hash around for lookups */
118 unsigned char *canon_enc;
119 int canon_enclen;
120} /* X509_NAME */;
121
122struct X509_extension_st {
123 ASN1_OBJECT *object;
124 ASN1_BOOLEAN critical;
125 ASN1_OCTET_STRING *value;
126} /* X509_EXTENSION */;
127
128struct x509_attributes_st {
129 ASN1_OBJECT *object;
130 STACK_OF(ASN1_TYPE) *set;
131} /* X509_ATTRIBUTE */;
132
133struct X509_req_info_st {
134 ASN1_ENCODING enc;
135 ASN1_INTEGER *version;
136 X509_NAME *subject;
137 X509_PUBKEY *pubkey;
138 /* d=2 hl=2 l= 0 cons: cont: 00 */
139 STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
140} /* X509_REQ_INFO */;
141
142struct X509_req_st {
143 X509_REQ_INFO *req_info;
144 X509_ALGOR *sig_alg;
145 ASN1_BIT_STRING *signature;
146 int references;
147} /* X509_REQ */;
148
149/*
150 * This stuff is certificate "auxiliary info" it contains details which are
151 * useful in certificate stores and databases. When used this is tagged onto
152 * the end of the certificate itself.
153 */
154typedef struct x509_cert_aux_st {
155 STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
156 STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
157 ASN1_UTF8STRING *alias; /* "friendly name" */
158 ASN1_OCTET_STRING *keyid; /* key id of private key */
159 STACK_OF(X509_ALGOR) *other; /* other unspecified info */
160} X509_CERT_AUX;
161
162X509_CERT_AUX *X509_CERT_AUX_new(void);
163void X509_CERT_AUX_free(X509_CERT_AUX *a);
164X509_CERT_AUX *d2i_X509_CERT_AUX(X509_CERT_AUX **a, const unsigned char **in, long len);
165int i2d_X509_CERT_AUX(X509_CERT_AUX *a, unsigned char **out);
166extern const ASN1_ITEM X509_CERT_AUX_it;
167int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
168
169struct x509_cinf_st {
170 ASN1_INTEGER *version; /* [ 0 ] default of v1 */
171 ASN1_INTEGER *serialNumber;
172 X509_ALGOR *signature;
173 X509_NAME *issuer;
174 X509_VAL *validity;
175 X509_NAME *subject;
176 X509_PUBKEY *key;
177 ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
178 ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
179 STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
180 ASN1_ENCODING enc;
181} /* X509_CINF */;
182
183struct x509_st {
184 X509_CINF *cert_info;
185 X509_ALGOR *sig_alg;
186 ASN1_BIT_STRING *signature;
187 int references;
188 CRYPTO_EX_DATA ex_data;
189 /* These contain copies of various extension values */
190 long ex_pathlen;
191 unsigned long ex_flags;
192 unsigned long ex_kusage;
193 unsigned long ex_xkusage;
194 unsigned long ex_nscert;
195 ASN1_OCTET_STRING *skid;
196 AUTHORITY_KEYID *akid;
197 STACK_OF(DIST_POINT) *crldp;
198 STACK_OF(GENERAL_NAME) *altname;
199 NAME_CONSTRAINTS *nc;
200#ifndef OPENSSL_NO_RFC3779
201 STACK_OF(IPAddressFamily) *rfc3779_addr;
202 ASIdentifiers *rfc3779_asid;
203#endif
204 unsigned char hash[X509_CERT_HASH_LEN];
205 X509_CERT_AUX *aux;
206} /* X509 */;
207
208struct x509_revoked_st {
209 ASN1_INTEGER *serialNumber;
210 ASN1_TIME *revocationDate;
211 STACK_OF(X509_EXTENSION) /* optional */ *extensions;
212 /* Set up if indirect CRL */
213 STACK_OF(GENERAL_NAME) *issuer;
214 /* Revocation reason */
215 int reason;
216 int sequence; /* load sequence */
217};
218
219struct X509_crl_info_st {
220 ASN1_INTEGER *version;
221 X509_ALGOR *sig_alg;
222 X509_NAME *issuer;
223 ASN1_TIME *lastUpdate;
224 ASN1_TIME *nextUpdate;
225 STACK_OF(X509_REVOKED) *revoked;
226 STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
227 ASN1_ENCODING enc;
228} /* X509_CRL_INFO */;
229
230struct X509_crl_st {
231 /* actual signature */
232 X509_CRL_INFO *crl;
233 X509_ALGOR *sig_alg;
234 ASN1_BIT_STRING *signature;
235 int references;
236 int flags;
237 /* Copies of various extensions */
238 AUTHORITY_KEYID *akid;
239 ISSUING_DIST_POINT *idp;
240 /* Convenient breakdown of IDP */
241 int idp_flags;
242 int idp_reasons;
243 /* CRL and base CRL numbers for delta processing */
244 ASN1_INTEGER *crl_number;
245 ASN1_INTEGER *base_crl_number;
246 unsigned char hash[X509_CRL_HASH_LEN];
247 STACK_OF(GENERAL_NAMES) *issuers;
248} /* X509_CRL */;
249
250struct pkcs8_priv_key_info_st {
251 ASN1_INTEGER *version;
252 X509_ALGOR *pkeyalg;
253 ASN1_OCTET_STRING *pkey;
254 STACK_OF(X509_ATTRIBUTE) *attributes;
255};
256
257struct x509_object_st {
258 /* one of the above types */
259 int type;
260 union {
261 X509 *x509;
262 X509_CRL *crl;
263 } data;
264} /* X509_OBJECT */;
265
266struct x509_lookup_method_st {
267 const char *name;
268 int (*new_item)(X509_LOOKUP *ctx);
269 void (*free)(X509_LOOKUP *ctx);
270 int (*ctrl)(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
271 char **ret);
272 int (*get_by_subject)(X509_LOOKUP *ctx, int type, X509_NAME *name,
273 X509_OBJECT *ret);
274} /* X509_LOOKUP_METHOD */;
275
276struct X509_VERIFY_PARAM_st {
277 char *name;
278 time_t check_time; /* Time to use */
279 unsigned long inh_flags; /* Inheritance flags */
280 unsigned long flags; /* Various verify flags */
281 int purpose; /* purpose to check untrusted certificates */
282 int trust; /* trust setting to check */
283 int depth; /* Verify depth */
284 int security_level; /* 'Security level', see SP800-57. */
285 STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
286 STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
287 unsigned int hostflags; /* Flags to control matching features */
288 char *peername; /* Matching hostname in peer certificate */
289 char *email; /* If not NULL email address to match */
290 size_t emaillen;
291 unsigned char *ip; /* If not NULL IP address to match */
292 size_t iplen; /* Length of IP address */
293 int poisoned;
294} /* X509_VERIFY_PARAM */;
295
296/*
297 * This is used to hold everything. It is used for all certificate
298 * validation. Once we have a certificate chain, the 'verify'
299 * function is then called to actually check the cert chain.
300 */
301struct x509_store_st {
302 /* The following is a cache of trusted certs */
303 STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
304
305 /* These are external lookup methods */
306 STACK_OF(X509_LOOKUP) *get_cert_methods;
307
308 X509_VERIFY_PARAM *param;
309
310 /* Callbacks for various operations */
311 int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */
312 int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */
313 int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
314
315 CRYPTO_EX_DATA ex_data;
316 int references;
317} /* X509_STORE */;
318
319/* This is the functions plus an instance of the local variables. */
320struct x509_lookup_st {
321 const X509_LOOKUP_METHOD *method; /* the functions */
322 void *method_data; /* method data */
323
324 X509_STORE *store_ctx; /* who owns us */
325} /* X509_LOOKUP */;
326
327/*
328 * This is used when verifying cert chains. Since the gathering of the cert
329 * chain can take some time (and has to be 'retried'), this needs to be kept
330 * and passed around.
331 */
332struct x509_store_ctx_st {
333 X509_STORE *store;
334 int current_method; /* used when looking up certs */
335
336 /* The following are set by the caller */
337 X509 *cert; /* The cert to check */
338 STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */
339 STACK_OF(X509) *trusted; /* trusted stack for use with get_issuer() */
340 STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */
341
342 X509_VERIFY_PARAM *param;
343
344 /* Callbacks for various operations */
345 int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */
346 int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */
347 int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */
348 int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
349
350 /* The following is built up */
351 int valid; /* if 0, rebuild chain */
352 int num_untrusted; /* number of untrusted certs in chain */
353 STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */
354
355 int explicit_policy; /* Require explicit policy value */
356
357 /* When something goes wrong, this is why */
358 int error_depth;
359 int error;
360 X509 *current_cert;
361 X509 *current_issuer; /* cert currently being tested as valid issuer */
362 X509_CRL *current_crl; /* current CRL */
363
364 int current_crl_score; /* score of current CRL */
365 unsigned int current_reasons; /* Reason mask */
366
367 X509_STORE_CTX *parent; /* For CRL path validation: parent context */
368
369 CRYPTO_EX_DATA ex_data;
370} /* X509_STORE_CTX */;
371
372int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet);
373
374int name_cmp(const char *name, const char *cmp);
375
376int X509_ALGOR_set_evp_md(X509_ALGOR *alg, const EVP_MD *md);
377int X509_ALGOR_set0_by_nid(X509_ALGOR *alg, int nid, int parameter_type,
378 void *parameter_value);
379
380int X509_policy_check(const STACK_OF(X509) *certs,
381 const STACK_OF(ASN1_OBJECT) *user_policies, unsigned long flags,
382 X509 **out_current_cert);
383
384PBEPARAM *PBEPARAM_new(void);
385void PBEPARAM_free(PBEPARAM *a);
386PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, const unsigned char **in, long len);
387int i2d_PBEPARAM(PBEPARAM *a, unsigned char **out);
388
389/* Password based encryption V2 structures */
390typedef struct PBE2PARAM_st {
391 X509_ALGOR *keyfunc;
392 X509_ALGOR *encryption;
393} PBE2PARAM;
394
395PBE2PARAM *PBE2PARAM_new(void);
396void PBE2PARAM_free(PBE2PARAM *a);
397PBE2PARAM *d2i_PBE2PARAM(PBE2PARAM **a, const unsigned char **in, long len);
398int i2d_PBE2PARAM(PBE2PARAM *a, unsigned char **out);
399extern const ASN1_ITEM PBE2PARAM_it;
400
401typedef struct PBKDF2PARAM_st {
402 /* Usually OCTET STRING but could be anything */
403 ASN1_TYPE *salt;
404 ASN1_INTEGER *iter;
405 ASN1_INTEGER *keylength;
406 X509_ALGOR *prf;
407} PBKDF2PARAM;
408
409PBKDF2PARAM *PBKDF2PARAM_new(void);
410void PBKDF2PARAM_free(PBKDF2PARAM *a);
411PBKDF2PARAM *d2i_PBKDF2PARAM(PBKDF2PARAM **a, const unsigned char **in, long len);
412int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **out);
413extern const ASN1_ITEM PBKDF2PARAM_it;
414
415int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
416 const unsigned char *salt, int saltlen);
417X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
418 unsigned char *salt, int saltlen);
419X509_ALGOR *PKCS5_pbe_set(int alg, int iter, const unsigned char *salt,
420 int saltlen);
421X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
422 int prf_nid, int keylen);
423
424int X509_PURPOSE_get_by_id(int id);
425int X509_PURPOSE_get_trust(const X509_PURPOSE *xp);
426
427int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
428 int lastpos);
429int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
430 const ASN1_OBJECT *obj, int lastpos);
431STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
432 X509_ATTRIBUTE *attr);
433STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
434 const ASN1_OBJECT *obj, int type, const unsigned char *bytes, int len);
435STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
436 int nid, int type, const unsigned char *bytes, int len);
437STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
438 const char *attrname, int type, const unsigned char *bytes, int len);
439void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
440 const ASN1_OBJECT *obj, int lastpos, int type);
441
442int X509_NAME_ENTRY_add_cbb(CBB *cbb, const X509_NAME_ENTRY *ne);
443
444int X509V3_add_value(const char *name, const char *value,
445 STACK_OF(CONF_VALUE) **extlist);
446int X509V3_add_value_uchar(const char *name, const unsigned char *value,
447 STACK_OF(CONF_VALUE) **extlist);
448int X509V3_add_value_bool(const char *name, int asn1_bool,
449 STACK_OF(CONF_VALUE) **extlist);
450int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint,
451 STACK_OF(CONF_VALUE) **extlist);
452
453int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool);
454int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint);
455
456STACK_OF(CONF_VALUE) *X509V3_get0_section(X509V3_CTX *ctx, const char *section);
457
458const X509V3_EXT_METHOD *x509v3_ext_method_authority_key_identifier(void);
459const X509V3_EXT_METHOD *x509v3_ext_method_basic_constraints(void);
460const X509V3_EXT_METHOD *x509v3_ext_method_certificate_issuer(void);
461const X509V3_EXT_METHOD *x509v3_ext_method_certificate_policies(void);
462const X509V3_EXT_METHOD *x509v3_ext_method_crl_distribution_points(void);
463const X509V3_EXT_METHOD *x509v3_ext_method_crl_number(void);
464const X509V3_EXT_METHOD *x509v3_ext_method_crl_reason(void);
465const X509V3_EXT_METHOD *x509v3_ext_method_ct_cert_scts(void);
466const X509V3_EXT_METHOD *x509v3_ext_method_ct_precert_poison(void);
467const X509V3_EXT_METHOD *x509v3_ext_method_ct_precert_scts(void);
468const X509V3_EXT_METHOD *x509v3_ext_method_delta_crl(void);
469const X509V3_EXT_METHOD *x509v3_ext_method_ext_key_usage(void);
470const X509V3_EXT_METHOD *x509v3_ext_method_freshest_crl(void);
471const X509V3_EXT_METHOD *x509v3_ext_method_hold_instruction_code(void);
472const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_CrlID(void);
473const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_Nonce(void);
474const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_acceptableResponses(void);
475const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_archiveCutoff(void);
476const X509V3_EXT_METHOD *x509v3_ext_method_id_pkix_OCSP_serviceLocator(void);
477const X509V3_EXT_METHOD *x509v3_ext_method_info_access(void);
478const X509V3_EXT_METHOD *x509v3_ext_method_inhibit_any_policy(void);
479const X509V3_EXT_METHOD *x509v3_ext_method_invalidity_date(void);
480const X509V3_EXT_METHOD *x509v3_ext_method_issuer_alt_name(void);
481const X509V3_EXT_METHOD *x509v3_ext_method_issuing_distribution_point(void);
482const X509V3_EXT_METHOD *x509v3_ext_method_key_usage(void);
483const X509V3_EXT_METHOD *x509v3_ext_method_name_constraints(void);
484const X509V3_EXT_METHOD *x509v3_ext_method_netscape_base_url(void);
485const X509V3_EXT_METHOD *x509v3_ext_method_netscape_ca_policy_url(void);
486const X509V3_EXT_METHOD *x509v3_ext_method_netscape_ca_revocation_url(void);
487const X509V3_EXT_METHOD *x509v3_ext_method_netscape_cert_type(void);
488const X509V3_EXT_METHOD *x509v3_ext_method_netscape_comment(void);
489const X509V3_EXT_METHOD *x509v3_ext_method_netscape_renewal_url(void);
490const X509V3_EXT_METHOD *x509v3_ext_method_netscape_revocation_url(void);
491const X509V3_EXT_METHOD *x509v3_ext_method_netscape_ssl_server_name(void);
492const X509V3_EXT_METHOD *x509v3_ext_method_policy_constraints(void);
493const X509V3_EXT_METHOD *x509v3_ext_method_policy_mappings(void);
494const X509V3_EXT_METHOD *x509v3_ext_method_private_key_usage_period(void);
495const X509V3_EXT_METHOD *x509v3_ext_method_sbgp_ipAddrBlock(void);
496const X509V3_EXT_METHOD *x509v3_ext_method_sbgp_autonomousSysNum(void);
497const X509V3_EXT_METHOD *x509v3_ext_method_sinfo_access(void);
498const X509V3_EXT_METHOD *x509v3_ext_method_subject_alt_name(void);
499const X509V3_EXT_METHOD *x509v3_ext_method_subject_key_identifier(void);
500
501__END_HIDDEN_DECLS
502
503#endif /* !HEADER_X509_LOCAL_H */
diff --git a/src/lib/libcrypto/x509/x509_lu.c b/src/lib/libcrypto/x509/x509_lu.c
deleted file mode 100644
index 0367794fca..0000000000
--- a/src/lib/libcrypto/x509/x509_lu.c
+++ /dev/null
@@ -1,883 +0,0 @@
1/* $OpenBSD: x509_lu.c,v 1.67 2025/03/09 15:20:20 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/err.h>
63#include <openssl/lhash.h>
64#include <openssl/x509.h>
65#include <openssl/x509v3.h>
66
67#include "x509_local.h"
68
69static int X509_OBJECT_up_ref_count(X509_OBJECT *a);
70
71static X509_LOOKUP *
72X509_LOOKUP_new(const X509_LOOKUP_METHOD *method)
73{
74 X509_LOOKUP *lu;
75
76 if ((lu = calloc(1, sizeof(*lu))) == NULL) {
77 X509error(ERR_R_MALLOC_FAILURE);
78 return NULL;
79 }
80
81 lu->method = method;
82
83 if (method->new_item != NULL && !method->new_item(lu)) {
84 free(lu);
85 return NULL;
86 }
87
88 return lu;
89}
90
91void
92X509_LOOKUP_free(X509_LOOKUP *ctx)
93{
94 if (ctx == NULL)
95 return;
96 if (ctx->method != NULL && ctx->method->free != NULL)
97 ctx->method->free(ctx);
98 free(ctx);
99}
100LCRYPTO_ALIAS(X509_LOOKUP_free);
101
102int
103X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
104 char **ret)
105{
106 if (ctx->method == NULL)
107 return -1;
108 if (ctx->method->ctrl == NULL)
109 return 1;
110 return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
111}
112LCRYPTO_ALIAS(X509_LOOKUP_ctrl);
113
114static int
115X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, X509_NAME *name,
116 X509_OBJECT *ret)
117{
118 if (ctx->method == NULL || ctx->method->get_by_subject == NULL)
119 return 0;
120 return ctx->method->get_by_subject(ctx, type, name, ret);
121}
122
123static int
124x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b)
125{
126 int ret;
127
128 if ((ret = (*a)->type - (*b)->type) != 0)
129 return ret;
130
131 switch ((*a)->type) {
132 case X509_LU_X509:
133 return X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
134 case X509_LU_CRL:
135 return X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
136 }
137 return 0;
138}
139
140X509_STORE *
141X509_STORE_new(void)
142{
143 X509_STORE *store;
144
145 if ((store = calloc(1, sizeof(*store))) == NULL)
146 goto err;
147
148 if ((store->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
149 goto err;
150 if ((store->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
151 goto err;
152 if ((store->param = X509_VERIFY_PARAM_new()) == NULL)
153 goto err;
154
155 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, store,
156 &store->ex_data))
157 goto err;
158
159 store->references = 1;
160
161 return store;
162
163 err:
164 X509error(ERR_R_MALLOC_FAILURE);
165 X509_STORE_free(store);
166
167 return NULL;
168}
169LCRYPTO_ALIAS(X509_STORE_new);
170
171X509_OBJECT *
172X509_OBJECT_new(void)
173{
174 X509_OBJECT *obj;
175
176 if ((obj = calloc(1, sizeof(*obj))) == NULL) {
177 X509error(ERR_R_MALLOC_FAILURE);
178 return NULL;
179 }
180
181 obj->type = X509_LU_NONE;
182
183 return obj;
184}
185LCRYPTO_ALIAS(X509_OBJECT_new);
186
187void
188X509_OBJECT_free(X509_OBJECT *a)
189{
190 if (a == NULL)
191 return;
192
193 switch (a->type) {
194 case X509_LU_X509:
195 X509_free(a->data.x509);
196 break;
197 case X509_LU_CRL:
198 X509_CRL_free(a->data.crl);
199 break;
200 }
201
202 free(a);
203}
204LCRYPTO_ALIAS(X509_OBJECT_free);
205
206static X509_OBJECT *
207x509_object_dup(const X509_OBJECT *obj)
208{
209 X509_OBJECT *copy;
210
211 if ((copy = X509_OBJECT_new()) == NULL) {
212 X509error(ERR_R_MALLOC_FAILURE);
213 return NULL;
214 }
215
216 copy->type = obj->type;
217 copy->data = obj->data;
218
219 X509_OBJECT_up_ref_count(copy);
220
221 return copy;
222}
223
224void
225X509_STORE_free(X509_STORE *store)
226{
227 if (store == NULL)
228 return;
229
230 if (CRYPTO_add(&store->references, -1, CRYPTO_LOCK_X509_STORE) > 0)
231 return;
232
233 sk_X509_LOOKUP_pop_free(store->get_cert_methods, X509_LOOKUP_free);
234 sk_X509_OBJECT_pop_free(store->objs, X509_OBJECT_free);
235
236 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, store, &store->ex_data);
237 X509_VERIFY_PARAM_free(store->param);
238 free(store);
239}
240LCRYPTO_ALIAS(X509_STORE_free);
241
242int
243X509_STORE_up_ref(X509_STORE *store)
244{
245 return CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE) > 1;
246}
247LCRYPTO_ALIAS(X509_STORE_up_ref);
248
249X509_LOOKUP *
250X509_STORE_add_lookup(X509_STORE *store, const X509_LOOKUP_METHOD *method)
251{
252 STACK_OF(X509_LOOKUP) *sk;
253 X509_LOOKUP *lu;
254 int i;
255
256 sk = store->get_cert_methods;
257 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
258 lu = sk_X509_LOOKUP_value(sk, i);
259 if (method == lu->method) {
260 return lu;
261 }
262 }
263
264 if ((lu = X509_LOOKUP_new(method)) == NULL)
265 return NULL;
266
267 lu->store_ctx = store;
268 if (sk_X509_LOOKUP_push(store->get_cert_methods, lu) <= 0) {
269 X509error(ERR_R_MALLOC_FAILURE);
270 X509_LOOKUP_free(lu);
271 return NULL;
272 }
273
274 return lu;
275}
276LCRYPTO_ALIAS(X509_STORE_add_lookup);
277
278X509_OBJECT *
279X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
280 X509_NAME *name)
281{
282 X509_OBJECT *obj;
283
284 if ((obj = X509_OBJECT_new()) == NULL)
285 return NULL;
286 if (!X509_STORE_CTX_get_by_subject(vs, type, name, obj)) {
287 X509_OBJECT_free(obj);
288 return NULL;
289 }
290
291 return obj;
292}
293LCRYPTO_ALIAS(X509_STORE_CTX_get_obj_by_subject);
294
295int
296X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
297 X509_NAME *name, X509_OBJECT *ret)
298{
299 X509_STORE *ctx = vs->store;
300 X509_LOOKUP *lu;
301 X509_OBJECT stmp, *tmp;
302 int i;
303
304 if (ctx == NULL)
305 return 0;
306
307 memset(&stmp, 0, sizeof(stmp));
308
309 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
310 tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
311 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
312
313 if (tmp == NULL || type == X509_LU_CRL) {
314 for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
315 lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
316 if (X509_LOOKUP_by_subject(lu, type, name, &stmp) != 0) {
317 tmp = &stmp;
318 break;
319 }
320 }
321 if (tmp == NULL)
322 return 0;
323 }
324
325 if (!X509_OBJECT_up_ref_count(tmp))
326 return 0;
327
328 *ret = *tmp;
329
330 return 1;
331}
332LCRYPTO_ALIAS(X509_STORE_CTX_get_by_subject);
333
334/* Add obj to the store. Takes ownership of obj. */
335static int
336X509_STORE_add_object(X509_STORE *store, X509_OBJECT *obj)
337{
338 int ret = 0;
339
340 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
341
342 if (X509_OBJECT_retrieve_match(store->objs, obj) != NULL) {
343 /* Object is already present in the store. That's fine. */
344 ret = 1;
345 goto out;
346 }
347
348 if (sk_X509_OBJECT_push(store->objs, obj) <= 0) {
349 X509error(ERR_R_MALLOC_FAILURE);
350 goto out;
351 }
352
353 obj = NULL;
354 ret = 1;
355
356 out:
357 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
358 X509_OBJECT_free(obj);
359
360 return ret;
361}
362
363int
364X509_STORE_add_cert(X509_STORE *store, X509 *x)
365{
366 X509_OBJECT *obj;
367
368 if (x == NULL)
369 return 0;
370
371 if ((obj = X509_OBJECT_new()) == NULL)
372 return 0;
373
374 if (!X509_up_ref(x)) {
375 X509_OBJECT_free(obj);
376 return 0;
377 }
378
379 obj->type = X509_LU_X509;
380 obj->data.x509 = x;
381
382 return X509_STORE_add_object(store, obj);
383}
384LCRYPTO_ALIAS(X509_STORE_add_cert);
385
386int
387X509_STORE_add_crl(X509_STORE *store, X509_CRL *x)
388{
389 X509_OBJECT *obj;
390
391 if (x == NULL)
392 return 0;
393
394 if ((obj = X509_OBJECT_new()) == NULL)
395 return 0;
396
397 if (!X509_CRL_up_ref(x)) {
398 X509_OBJECT_free(obj);
399 return 0;
400 }
401
402 obj->type = X509_LU_CRL;
403 obj->data.crl = x;
404
405 return X509_STORE_add_object(store, obj);
406}
407LCRYPTO_ALIAS(X509_STORE_add_crl);
408
409static int
410X509_OBJECT_up_ref_count(X509_OBJECT *a)
411{
412 switch (a->type) {
413 case X509_LU_X509:
414 return X509_up_ref(a->data.x509);
415 case X509_LU_CRL:
416 return X509_CRL_up_ref(a->data.crl);
417 }
418 return 1;
419}
420
421X509_LOOKUP_TYPE
422X509_OBJECT_get_type(const X509_OBJECT *a)
423{
424 return a->type;
425}
426LCRYPTO_ALIAS(X509_OBJECT_get_type);
427
428static int
429x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
430 X509_NAME *name, int *pnmatch)
431{
432 X509_OBJECT stmp;
433 X509 x509_s;
434 X509_CINF cinf_s;
435 X509_CRL crl_s;
436 X509_CRL_INFO crl_info_s;
437 int idx;
438
439 stmp.type = type;
440 switch (type) {
441 case X509_LU_X509:
442 stmp.data.x509 = &x509_s;
443 x509_s.cert_info = &cinf_s;
444 cinf_s.subject = name;
445 break;
446 case X509_LU_CRL:
447 stmp.data.crl = &crl_s;
448 crl_s.crl = &crl_info_s;
449 crl_info_s.issuer = name;
450 break;
451 default:
452 return -1;
453 }
454
455 idx = sk_X509_OBJECT_find(h, &stmp);
456 if (idx >= 0 && pnmatch) {
457 int tidx;
458 const X509_OBJECT *tobj, *pstmp;
459
460 *pnmatch = 1;
461 pstmp = &stmp;
462 for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
463 tobj = sk_X509_OBJECT_value(h, tidx);
464 if (x509_object_cmp(&tobj, &pstmp))
465 break;
466 (*pnmatch)++;
467 }
468 }
469 return idx;
470}
471
472int
473X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
474 X509_NAME *name)
475{
476 return x509_object_idx_cnt(h, type, name, NULL);
477}
478LCRYPTO_ALIAS(X509_OBJECT_idx_by_subject);
479
480X509_OBJECT *
481X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
482 X509_NAME *name)
483{
484 int idx;
485
486 idx = X509_OBJECT_idx_by_subject(h, type, name);
487 if (idx == -1)
488 return NULL;
489 return sk_X509_OBJECT_value(h, idx);
490}
491LCRYPTO_ALIAS(X509_OBJECT_retrieve_by_subject);
492
493X509 *
494X509_OBJECT_get0_X509(const X509_OBJECT *xo)
495{
496 if (xo != NULL && xo->type == X509_LU_X509)
497 return xo->data.x509;
498 return NULL;
499}
500LCRYPTO_ALIAS(X509_OBJECT_get0_X509);
501
502X509_CRL *
503X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo)
504{
505 if (xo != NULL && xo->type == X509_LU_CRL)
506 return xo->data.crl;
507 return NULL;
508}
509LCRYPTO_ALIAS(X509_OBJECT_get0_X509_CRL);
510
511static STACK_OF(X509) *
512X509_get1_certs_from_cache(X509_STORE *store, X509_NAME *name)
513{
514 STACK_OF(X509) *sk = NULL;
515 X509 *x = NULL;
516 X509_OBJECT *obj;
517 int i, idx, cnt;
518
519 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
520
521 idx = x509_object_idx_cnt(store->objs, X509_LU_X509, name, &cnt);
522 if (idx < 0)
523 goto err;
524
525 if ((sk = sk_X509_new_null()) == NULL)
526 goto err;
527
528 for (i = 0; i < cnt; i++, idx++) {
529 obj = sk_X509_OBJECT_value(store->objs, idx);
530
531 x = obj->data.x509;
532 if (!X509_up_ref(x)) {
533 x = NULL;
534 goto err;
535 }
536 if (!sk_X509_push(sk, x))
537 goto err;
538 }
539
540 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
541
542 return sk;
543
544 err:
545 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
546 sk_X509_pop_free(sk, X509_free);
547 X509_free(x);
548
549 return NULL;
550}
551
552STACK_OF(X509) *
553X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *name)
554{
555 X509_STORE *store = ctx->store;
556 STACK_OF(X509) *sk;
557 X509_OBJECT *obj;
558
559 if (store == NULL)
560 return NULL;
561
562 if ((sk = X509_get1_certs_from_cache(store, name)) != NULL)
563 return sk;
564
565 /* Nothing found: do lookup to possibly add new objects to cache. */
566 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, name);
567 if (obj == NULL)
568 return NULL;
569 X509_OBJECT_free(obj);
570
571 return X509_get1_certs_from_cache(store, name);
572}
573LCRYPTO_ALIAS(X509_STORE_CTX_get1_certs);
574
575STACK_OF(X509_CRL) *
576X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *name)
577{
578 X509_STORE *store = ctx->store;
579 STACK_OF(X509_CRL) *sk = NULL;
580 X509_CRL *x = NULL;
581 X509_OBJECT *obj = NULL;
582 int i, idx, cnt;
583
584 if (store == NULL)
585 return NULL;
586
587 /* Always do lookup to possibly add new CRLs to cache */
588 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_CRL, name);
589 if (obj == NULL)
590 return NULL;
591
592 X509_OBJECT_free(obj);
593 obj = NULL;
594
595 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
596 idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, name, &cnt);
597 if (idx < 0)
598 goto err;
599
600 if ((sk = sk_X509_CRL_new_null()) == NULL)
601 goto err;
602
603 for (i = 0; i < cnt; i++, idx++) {
604 obj = sk_X509_OBJECT_value(store->objs, idx);
605
606 x = obj->data.crl;
607 if (!X509_CRL_up_ref(x)) {
608 x = NULL;
609 goto err;
610 }
611 if (!sk_X509_CRL_push(sk, x))
612 goto err;
613 }
614
615 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
616 return sk;
617
618 err:
619 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
620 X509_CRL_free(x);
621 sk_X509_CRL_pop_free(sk, X509_CRL_free);
622 return NULL;
623}
624LCRYPTO_ALIAS(X509_STORE_CTX_get1_crls);
625
626X509_OBJECT *
627X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
628{
629 int idx, i;
630 X509_OBJECT *obj;
631
632 idx = sk_X509_OBJECT_find(h, x);
633 if (idx == -1)
634 return NULL;
635 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
636 return sk_X509_OBJECT_value(h, idx);
637 for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
638 obj = sk_X509_OBJECT_value(h, i);
639 if (x509_object_cmp((const X509_OBJECT **)&obj,
640 (const X509_OBJECT **)&x))
641 return NULL;
642 if (x->type == X509_LU_X509) {
643 if (!X509_cmp(obj->data.x509, x->data.x509))
644 return obj;
645 } else if (x->type == X509_LU_CRL) {
646 if (!X509_CRL_match(obj->data.crl, x->data.crl))
647 return obj;
648 } else
649 return obj;
650 }
651 return NULL;
652}
653LCRYPTO_ALIAS(X509_OBJECT_retrieve_match);
654
655/* Try to get issuer certificate from store. Due to limitations
656 * of the API this can only retrieve a single certificate matching
657 * a given subject name. However it will fill the cache with all
658 * matching certificates, so we can examine the cache for all
659 * matches.
660 *
661 * Return values are:
662 * 1 lookup successful.
663 * 0 certificate not found.
664 * -1 some other error.
665 */
666int
667X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x)
668{
669 X509_NAME *xn;
670 X509_OBJECT *obj, *pobj;
671 X509 *issuer = NULL;
672 int i, idx, ret;
673
674 *out_issuer = NULL;
675
676 xn = X509_get_issuer_name(x);
677 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, xn);
678 if (obj == NULL)
679 return 0;
680
681 if ((issuer = X509_OBJECT_get0_X509(obj)) == NULL) {
682 X509_OBJECT_free(obj);
683 return 0;
684 }
685 if (!X509_up_ref(issuer)) {
686 X509_OBJECT_free(obj);
687 return -1;
688 }
689
690 /* If certificate matches all OK */
691 if (ctx->check_issued(ctx, x, issuer)) {
692 if (x509_check_cert_time(ctx, issuer, -1)) {
693 *out_issuer = issuer;
694 X509_OBJECT_free(obj);
695 return 1;
696 }
697 }
698 X509_free(issuer);
699 issuer = NULL;
700 X509_OBJECT_free(obj);
701 obj = NULL;
702
703 if (ctx->store == NULL)
704 return 0;
705
706 /* Else find index of first cert accepted by 'check_issued' */
707 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
708 idx = X509_OBJECT_idx_by_subject(ctx->store->objs, X509_LU_X509, xn);
709 if (idx != -1) /* should be true as we've had at least one match */ {
710 /* Look through all matching certs for suitable issuer */
711 for (i = idx; i < sk_X509_OBJECT_num(ctx->store->objs); i++) {
712 pobj = sk_X509_OBJECT_value(ctx->store->objs, i);
713 /* See if we've run past the matches */
714 if (pobj->type != X509_LU_X509)
715 break;
716 if (X509_NAME_cmp(xn,
717 X509_get_subject_name(pobj->data.x509)))
718 break;
719 if (ctx->check_issued(ctx, x, pobj->data.x509)) {
720 issuer = pobj->data.x509;
721 /*
722 * If times check, exit with match,
723 * otherwise keep looking. Leave last
724 * match in issuer so we return nearest
725 * match if no certificate time is OK.
726 */
727 if (x509_check_cert_time(ctx, issuer, -1))
728 break;
729 }
730 }
731 }
732 ret = 0;
733 if (issuer != NULL) {
734 if (!X509_up_ref(issuer)) {
735 ret = -1;
736 } else {
737 *out_issuer = issuer;
738 ret = 1;
739 }
740 }
741 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
742 return ret;
743}
744LCRYPTO_ALIAS(X509_STORE_CTX_get1_issuer);
745
746STACK_OF(X509_OBJECT) *
747X509_STORE_get0_objects(X509_STORE *xs)
748{
749 return xs->objs;
750}
751LCRYPTO_ALIAS(X509_STORE_get0_objects);
752
753static STACK_OF(X509_OBJECT) *
754sk_X509_OBJECT_deep_copy(const STACK_OF(X509_OBJECT) *objs)
755{
756 STACK_OF(X509_OBJECT) *copy = NULL;
757 X509_OBJECT *obj = NULL;
758 int i;
759
760 if ((copy = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) {
761 X509error(ERR_R_MALLOC_FAILURE);
762 goto err;
763 }
764
765 for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
766 if ((obj = x509_object_dup(sk_X509_OBJECT_value(objs, i))) == NULL)
767 goto err;
768 if (!sk_X509_OBJECT_push(copy, obj))
769 goto err;
770 obj = NULL;
771 }
772
773 return copy;
774
775 err:
776 X509_OBJECT_free(obj);
777 sk_X509_OBJECT_pop_free(copy, X509_OBJECT_free);
778
779 return NULL;
780}
781
782STACK_OF(X509_OBJECT) *
783X509_STORE_get1_objects(X509_STORE *store)
784{
785 STACK_OF(X509_OBJECT) *objs;
786
787 if (store == NULL) {
788 X509error(ERR_R_PASSED_NULL_PARAMETER);
789 return NULL;
790 }
791
792 CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE);
793 objs = sk_X509_OBJECT_deep_copy(store->objs);
794 CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE);
795
796 return objs;
797}
798LCRYPTO_ALIAS(X509_STORE_get1_objects);
799
800void *
801X509_STORE_get_ex_data(X509_STORE *xs, int idx)
802{
803 return CRYPTO_get_ex_data(&xs->ex_data, idx);
804}
805LCRYPTO_ALIAS(X509_STORE_get_ex_data);
806
807int
808X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data)
809{
810 return CRYPTO_set_ex_data(&xs->ex_data, idx, data);
811}
812LCRYPTO_ALIAS(X509_STORE_set_ex_data);
813
814int
815X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
816{
817 return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
818}
819LCRYPTO_ALIAS(X509_STORE_set_flags);
820
821int
822X509_STORE_set_depth(X509_STORE *ctx, int depth)
823{
824 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
825 return 1;
826}
827LCRYPTO_ALIAS(X509_STORE_set_depth);
828
829int
830X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
831{
832 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
833}
834LCRYPTO_ALIAS(X509_STORE_set_purpose);
835
836int
837X509_STORE_set_trust(X509_STORE *ctx, int trust)
838{
839 return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
840}
841LCRYPTO_ALIAS(X509_STORE_set_trust);
842
843int
844X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
845{
846 return X509_VERIFY_PARAM_set1(ctx->param, param);
847}
848LCRYPTO_ALIAS(X509_STORE_set1_param);
849
850X509_VERIFY_PARAM *
851X509_STORE_get0_param(X509_STORE *ctx)
852{
853 return ctx->param;
854}
855LCRYPTO_ALIAS(X509_STORE_get0_param);
856
857void
858X509_STORE_set_verify(X509_STORE *store, X509_STORE_CTX_verify_fn verify)
859{
860 store->verify = verify;
861}
862LCRYPTO_ALIAS(X509_STORE_set_verify);
863
864X509_STORE_CTX_verify_fn
865X509_STORE_get_verify(X509_STORE *store)
866{
867 return store->verify;
868}
869LCRYPTO_ALIAS(X509_STORE_get_verify);
870
871void
872X509_STORE_set_verify_cb(X509_STORE *store, X509_STORE_CTX_verify_cb verify_cb)
873{
874 store->verify_cb = verify_cb;
875}
876LCRYPTO_ALIAS(X509_STORE_set_verify_cb);
877
878X509_STORE_CTX_verify_cb
879X509_STORE_get_verify_cb(X509_STORE *store)
880{
881 return store->verify_cb;
882}
883LCRYPTO_ALIAS(X509_STORE_get_verify_cb);
diff --git a/src/lib/libcrypto/x509/x509_ncons.c b/src/lib/libcrypto/x509/x509_ncons.c
deleted file mode 100644
index 148a66e887..0000000000
--- a/src/lib/libcrypto/x509/x509_ncons.c
+++ /dev/null
@@ -1,569 +0,0 @@
1/* $OpenBSD: x509_ncons.c,v 1.11 2024/07/13 15:08:58 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2003 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1t.h>
63#include <openssl/conf.h>
64#include <openssl/err.h>
65#include <openssl/x509v3.h>
66
67#include "x509_local.h"
68
69static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
70 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
71static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
72 void *a, BIO *bp, int ind);
73static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
74 STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name);
75static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
76
77static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
78static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
79static int nc_dn(X509_NAME *sub, X509_NAME *nm);
80static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
81static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
82static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
83
84static const X509V3_EXT_METHOD x509v3_ext_name_constraints = {
85 .ext_nid = NID_name_constraints,
86 .ext_flags = 0,
87 .it = &NAME_CONSTRAINTS_it,
88 .ext_new = NULL,
89 .ext_free = NULL,
90 .d2i = NULL,
91 .i2d = NULL,
92 .i2s = NULL,
93 .s2i = NULL,
94 .i2v = NULL,
95 .v2i = v2i_NAME_CONSTRAINTS,
96 .i2r = i2r_NAME_CONSTRAINTS,
97 .r2i = NULL,
98 .usr_data = NULL,
99};
100
101const X509V3_EXT_METHOD *
102x509v3_ext_method_name_constraints(void)
103{
104 return &x509v3_ext_name_constraints;
105}
106
107static const ASN1_TEMPLATE GENERAL_SUBTREE_seq_tt[] = {
108 {
109 .flags = 0,
110 .tag = 0,
111 .offset = offsetof(GENERAL_SUBTREE, base),
112 .field_name = "base",
113 .item = &GENERAL_NAME_it,
114 },
115 {
116 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
117 .tag = 0,
118 .offset = offsetof(GENERAL_SUBTREE, minimum),
119 .field_name = "minimum",
120 .item = &ASN1_INTEGER_it,
121 },
122 {
123 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
124 .tag = 1,
125 .offset = offsetof(GENERAL_SUBTREE, maximum),
126 .field_name = "maximum",
127 .item = &ASN1_INTEGER_it,
128 },
129};
130
131const ASN1_ITEM GENERAL_SUBTREE_it = {
132 .itype = ASN1_ITYPE_SEQUENCE,
133 .utype = V_ASN1_SEQUENCE,
134 .templates = GENERAL_SUBTREE_seq_tt,
135 .tcount = sizeof(GENERAL_SUBTREE_seq_tt) / sizeof(ASN1_TEMPLATE),
136 .funcs = NULL,
137 .size = sizeof(GENERAL_SUBTREE),
138 .sname = "GENERAL_SUBTREE",
139};
140LCRYPTO_ALIAS(GENERAL_SUBTREE_it);
141
142static const ASN1_TEMPLATE NAME_CONSTRAINTS_seq_tt[] = {
143 {
144 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
145 .tag = 0,
146 .offset = offsetof(NAME_CONSTRAINTS, permittedSubtrees),
147 .field_name = "permittedSubtrees",
148 .item = &GENERAL_SUBTREE_it,
149 },
150 {
151 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
152 .tag = 1,
153 .offset = offsetof(NAME_CONSTRAINTS, excludedSubtrees),
154 .field_name = "excludedSubtrees",
155 .item = &GENERAL_SUBTREE_it,
156 },
157};
158
159const ASN1_ITEM NAME_CONSTRAINTS_it = {
160 .itype = ASN1_ITYPE_SEQUENCE,
161 .utype = V_ASN1_SEQUENCE,
162 .templates = NAME_CONSTRAINTS_seq_tt,
163 .tcount = sizeof(NAME_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE),
164 .funcs = NULL,
165 .size = sizeof(NAME_CONSTRAINTS),
166 .sname = "NAME_CONSTRAINTS",
167};
168LCRYPTO_ALIAS(NAME_CONSTRAINTS_it);
169
170
171GENERAL_SUBTREE *
172GENERAL_SUBTREE_new(void)
173{
174 return (GENERAL_SUBTREE*)ASN1_item_new(&GENERAL_SUBTREE_it);
175}
176LCRYPTO_ALIAS(GENERAL_SUBTREE_new);
177
178void
179GENERAL_SUBTREE_free(GENERAL_SUBTREE *a)
180{
181 ASN1_item_free((ASN1_VALUE *)a, &GENERAL_SUBTREE_it);
182}
183LCRYPTO_ALIAS(GENERAL_SUBTREE_free);
184
185NAME_CONSTRAINTS *
186NAME_CONSTRAINTS_new(void)
187{
188 return (NAME_CONSTRAINTS*)ASN1_item_new(&NAME_CONSTRAINTS_it);
189}
190LCRYPTO_ALIAS(NAME_CONSTRAINTS_new);
191
192void
193NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a)
194{
195 ASN1_item_free((ASN1_VALUE *)a, &NAME_CONSTRAINTS_it);
196}
197LCRYPTO_ALIAS(NAME_CONSTRAINTS_free);
198
199static void *
200v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
201 STACK_OF(CONF_VALUE) *nval)
202{
203 int i;
204 CONF_VALUE tval, *val;
205 STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
206 NAME_CONSTRAINTS *ncons = NULL;
207 GENERAL_SUBTREE *sub = NULL;
208
209 ncons = NAME_CONSTRAINTS_new();
210 if (!ncons)
211 goto memerr;
212 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
213 val = sk_CONF_VALUE_value(nval, i);
214 if (!strncmp(val->name, "permitted", 9) && val->name[9]) {
215 ptree = &ncons->permittedSubtrees;
216 tval.name = val->name + 10;
217 } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) {
218 ptree = &ncons->excludedSubtrees;
219 tval.name = val->name + 9;
220 } else {
221 X509V3error(X509V3_R_INVALID_SYNTAX);
222 goto err;
223 }
224 tval.value = val->value;
225 sub = GENERAL_SUBTREE_new();
226 if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
227 goto err;
228 if (!*ptree)
229 *ptree = sk_GENERAL_SUBTREE_new_null();
230 if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
231 goto memerr;
232 sub = NULL;
233 }
234
235 return ncons;
236
237memerr:
238 X509V3error(ERR_R_MALLOC_FAILURE);
239err:
240 NAME_CONSTRAINTS_free(ncons);
241 GENERAL_SUBTREE_free(sub);
242 return NULL;
243}
244
245static int
246i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, BIO *bp, int ind)
247{
248 NAME_CONSTRAINTS *ncons = a;
249
250 do_i2r_name_constraints(method, ncons->permittedSubtrees,
251 bp, ind, "Permitted");
252 do_i2r_name_constraints(method, ncons->excludedSubtrees,
253 bp, ind, "Excluded");
254 return 1;
255}
256
257static int
258do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
259 STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, int ind, char *name)
260{
261 GENERAL_SUBTREE *tree;
262 int i;
263
264 if (sk_GENERAL_SUBTREE_num(trees) > 0)
265 BIO_printf(bp, "%*s%s:\n", ind, "", name);
266 for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) {
267 tree = sk_GENERAL_SUBTREE_value(trees, i);
268 BIO_printf(bp, "%*s", ind + 2, "");
269 if (tree->base->type == GEN_IPADD)
270 print_nc_ipadd(bp, tree->base->d.ip);
271 else
272 GENERAL_NAME_print(bp, tree->base);
273 BIO_puts(bp, "\n");
274 }
275 return 1;
276}
277
278static int
279print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
280{
281 int i, len;
282 unsigned char *p;
283
284 p = ip->data;
285 len = ip->length;
286 BIO_puts(bp, "IP:");
287 if (len == 8) {
288 BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
289 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
290 } else if (len == 32) {
291 for (i = 0; i < 16; i++) {
292 BIO_printf(bp, "%X", p[0] << 8 | p[1]);
293 p += 2;
294 if (i == 7)
295 BIO_puts(bp, "/");
296 else if (i != 15)
297 BIO_puts(bp, ":");
298 }
299 } else
300 BIO_printf(bp, "IP Address:<invalid>");
301 return 1;
302}
303
304/* Check a certificate conforms to a specified set of constraints.
305 * Return values:
306 * X509_V_OK: All constraints obeyed.
307 * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
308 * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
309 * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
310 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type.
311 * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
312 * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
313 */
314
315int
316NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
317{
318 int r, i;
319 X509_NAME *nm;
320
321 nm = X509_get_subject_name(x);
322
323 if (X509_NAME_entry_count(nm) > 0) {
324 GENERAL_NAME gntmp;
325 gntmp.type = GEN_DIRNAME;
326 gntmp.d.directoryName = nm;
327
328 r = nc_match(&gntmp, nc);
329
330 if (r != X509_V_OK)
331 return r;
332
333 gntmp.type = GEN_EMAIL;
334
335 /* Process any email address attributes in subject name */
336
337 for (i = -1;;) {
338 X509_NAME_ENTRY *ne;
339 i = X509_NAME_get_index_by_NID(nm,
340 NID_pkcs9_emailAddress, i);
341 if (i == -1)
342 break;
343 ne = X509_NAME_get_entry(nm, i);
344 gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
345 if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
346 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
347
348 r = nc_match(&gntmp, nc);
349
350 if (r != X509_V_OK)
351 return r;
352 }
353
354 }
355
356 for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) {
357 GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
358 r = nc_match(gen, nc);
359 if (r != X509_V_OK)
360 return r;
361 }
362 return X509_V_OK;
363}
364LCRYPTO_ALIAS(NAME_CONSTRAINTS_check);
365static int
366nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
367{
368 GENERAL_SUBTREE *sub;
369 int i, r, match = 0;
370
371 /* Permitted subtrees: if any subtrees exist of matching the type
372 * at least one subtree must match.
373 */
374
375 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
376 sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
377 if (gen->type != sub->base->type)
378 continue;
379 if (sub->minimum || sub->maximum)
380 return X509_V_ERR_SUBTREE_MINMAX;
381 /* If we already have a match don't bother trying any more */
382 if (match == 2)
383 continue;
384 if (match == 0)
385 match = 1;
386 r = nc_match_single(gen, sub->base);
387 if (r == X509_V_OK)
388 match = 2;
389 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
390 return r;
391 }
392
393 if (match == 1)
394 return X509_V_ERR_PERMITTED_VIOLATION;
395
396 /* Excluded subtrees: must not match any of these */
397
398 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
399 sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
400 if (gen->type != sub->base->type)
401 continue;
402 if (sub->minimum || sub->maximum)
403 return X509_V_ERR_SUBTREE_MINMAX;
404
405 r = nc_match_single(gen, sub->base);
406 if (r == X509_V_OK)
407 return X509_V_ERR_EXCLUDED_VIOLATION;
408 else if (r != X509_V_ERR_PERMITTED_VIOLATION)
409 return r;
410
411 }
412
413 return X509_V_OK;
414}
415
416static int
417nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
418{
419 switch (base->type) {
420 case GEN_DIRNAME:
421 return nc_dn(gen->d.directoryName, base->d.directoryName);
422
423 case GEN_DNS:
424 return nc_dns(gen->d.dNSName, base->d.dNSName);
425
426 case GEN_EMAIL:
427 return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
428
429 case GEN_URI:
430 return nc_uri(gen->d.uniformResourceIdentifier,
431 base->d.uniformResourceIdentifier);
432
433 default:
434 return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
435 }
436}
437
438/* directoryName name constraint matching.
439 * The canonical encoding of X509_NAME makes this comparison easy. It is
440 * matched if the subtree is a subset of the name.
441 */
442
443static int
444nc_dn(X509_NAME *nm, X509_NAME *base)
445{
446 /* Ensure canonical encodings are up to date. */
447 if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
448 return X509_V_ERR_OUT_OF_MEM;
449 if (base->modified && i2d_X509_NAME(base, NULL) < 0)
450 return X509_V_ERR_OUT_OF_MEM;
451 if (base->canon_enclen > nm->canon_enclen)
452 return X509_V_ERR_PERMITTED_VIOLATION;
453 if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
454 return X509_V_ERR_PERMITTED_VIOLATION;
455 return X509_V_OK;
456}
457
458static int
459nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
460{
461 char *baseptr = (char *)base->data;
462 char *dnsptr = (char *)dns->data;
463
464 /* Empty matches everything */
465 if (!*baseptr)
466 return X509_V_OK;
467 /* Otherwise can add zero or more components on the left so
468 * compare RHS and if dns is longer and expect '.' as preceding
469 * character.
470 */
471 if (dns->length > base->length) {
472 dnsptr += dns->length - base->length;
473 if (baseptr[0] != '.' && dnsptr[-1] != '.')
474 return X509_V_ERR_PERMITTED_VIOLATION;
475 }
476
477 if (strcasecmp(baseptr, dnsptr))
478 return X509_V_ERR_PERMITTED_VIOLATION;
479
480 return X509_V_OK;
481}
482
483static int
484nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
485{
486 const char *baseptr = (char *)base->data;
487 const char *emlptr = (char *)eml->data;
488 const char *baseat = strchr(baseptr, '@');
489 const char *emlat = strchr(emlptr, '@');
490
491 if (!emlat)
492 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
493 /* Special case: initial '.' is RHS match */
494 if (!baseat && (*baseptr == '.')) {
495 if (eml->length > base->length) {
496 emlptr += eml->length - base->length;
497 if (!strcasecmp(baseptr, emlptr))
498 return X509_V_OK;
499 }
500 return X509_V_ERR_PERMITTED_VIOLATION;
501 }
502
503 /* If we have anything before '@' match local part */
504
505 if (baseat) {
506 if (baseat != baseptr) {
507 if ((baseat - baseptr) != (emlat - emlptr))
508 return X509_V_ERR_PERMITTED_VIOLATION;
509 /* Case sensitive match of local part */
510 if (strncmp(baseptr, emlptr, emlat - emlptr))
511 return X509_V_ERR_PERMITTED_VIOLATION;
512 }
513 /* Position base after '@' */
514 baseptr = baseat + 1;
515 }
516 emlptr = emlat + 1;
517 /* Just have hostname left to match: case insensitive */
518 if (strcasecmp(baseptr, emlptr))
519 return X509_V_ERR_PERMITTED_VIOLATION;
520
521 return X509_V_OK;
522}
523
524static int
525nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
526{
527 const char *baseptr = (char *)base->data;
528 const char *hostptr = (char *)uri->data;
529 const char *p = strchr(hostptr, ':');
530 int hostlen;
531
532 /* Check for foo:// and skip past it */
533 if (!p || (p[1] != '/') || (p[2] != '/'))
534 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
535 hostptr = p + 3;
536
537 /* Determine length of hostname part of URI */
538
539 /* Look for a port indicator as end of hostname first */
540
541 p = strchr(hostptr, ':');
542 /* Otherwise look for trailing slash */
543 if (!p)
544 p = strchr(hostptr, '/');
545
546 if (!p)
547 hostlen = strlen(hostptr);
548 else
549 hostlen = p - hostptr;
550
551 if (hostlen == 0)
552 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
553
554 /* Special case: initial '.' is RHS match */
555 if (*baseptr == '.') {
556 if (hostlen > base->length) {
557 p = hostptr + hostlen - base->length;
558 if (!strncasecmp(p, baseptr, base->length))
559 return X509_V_OK;
560 }
561 return X509_V_ERR_PERMITTED_VIOLATION;
562 }
563
564 if ((base->length != (int)hostlen) ||
565 strncasecmp(hostptr, baseptr, hostlen))
566 return X509_V_ERR_PERMITTED_VIOLATION;
567
568 return X509_V_OK;
569}
diff --git a/src/lib/libcrypto/x509/x509_obj.c b/src/lib/libcrypto/x509/x509_obj.c
deleted file mode 100644
index db1741cc9e..0000000000
--- a/src/lib/libcrypto/x509/x509_obj.c
+++ /dev/null
@@ -1,198 +0,0 @@
1/* $OpenBSD: x509_obj.c,v 1.25 2025/01/27 04:24:46 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdint.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
63
64#include <openssl/asn1.h>
65#include <openssl/objects.h>
66#include <openssl/x509.h>
67
68#include "bytestring.h"
69#include "x509_local.h"
70
71static int
72X509_NAME_ENTRY_add_object_cbb(CBB *cbb, const ASN1_OBJECT *aobj)
73{
74 const char *str;
75 char buf[80];
76 int nid;
77
78 /* Prefer SN over LN, and fall back to textual representation of OID. */
79 if ((nid = OBJ_obj2nid(aobj)) != NID_undef) {
80 if ((str = OBJ_nid2sn(nid)) != NULL)
81 return CBB_add_bytes(cbb, str, strlen(str));
82 if ((str = OBJ_nid2ln(nid)) != NULL)
83 return CBB_add_bytes(cbb, str, strlen(str));
84 }
85 if (OBJ_obj2txt(buf, sizeof(buf), aobj, 1) == 0)
86 return 0;
87 return CBB_add_bytes(cbb, buf, strlen(buf));
88}
89
90static int
91X509_NAME_ENTRY_add_u8_cbb(CBB *cbb, uint8_t u8)
92{
93 static const char hex[] = "0123456789ABCDEF";
94
95 if (' ' <= u8 && u8 <= '~')
96 return CBB_add_u8(cbb, u8);
97
98 if (!CBB_add_u8(cbb, '\\'))
99 return 0;
100 if (!CBB_add_u8(cbb, 'x'))
101 return 0;
102 if (!CBB_add_u8(cbb, hex[u8 >> 4]))
103 return 0;
104 if (!CBB_add_u8(cbb, hex[u8 & 0xf]))
105 return 0;
106 return 1;
107}
108
109static int
110X509_NAME_ENTRY_add_value_cbb(CBB *cbb, const ASN1_STRING *astr)
111{
112 CBS cbs;
113 uint8_t u8;
114 size_t i;
115 int mask[4] = { 1, 1, 1, 1 };
116
117 if (astr->type == V_ASN1_GENERALSTRING && astr->length % 4 == 0) {
118 int gs_mask[4] = { 0, 0, 0, 0 };
119
120 i = 0;
121 CBS_init(&cbs, astr->data, astr->length);
122 while (CBS_len(&cbs) > 0) {
123 if (!CBS_get_u8(&cbs, &u8))
124 return 0;
125
126 gs_mask[i++ & 0x3] |= u8;
127 }
128
129 if (gs_mask[0] == 0 && gs_mask[1] == 0 && gs_mask[2] == 0)
130 mask[0] = mask[1] = mask[2] = 0;
131 }
132
133 i = 0;
134 CBS_init(&cbs, astr->data, astr->length);
135 while (CBS_len(&cbs) > 0) {
136 if (!CBS_get_u8(&cbs, &u8))
137 return 0;
138 if (mask[i++ & 0x3] == 0)
139 continue;
140 if (!X509_NAME_ENTRY_add_u8_cbb(cbb, u8))
141 return 0;
142 }
143
144 return 1;
145}
146
147int
148X509_NAME_ENTRY_add_cbb(CBB *cbb, const X509_NAME_ENTRY *ne)
149{
150 if (!X509_NAME_ENTRY_add_object_cbb(cbb, ne->object))
151 return 0;
152 if (!CBB_add_u8(cbb, '='))
153 return 0;
154 if (!X509_NAME_ENTRY_add_value_cbb(cbb, ne->value))
155 return 0;
156 return 1;
157}
158
159char *
160X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
161{
162 CBB cbb;
163 const X509_NAME_ENTRY *ne;
164 uint8_t *line = NULL;
165 size_t line_len = 0;
166 int i;
167
168 if (!CBB_init(&cbb, 0))
169 goto err;
170
171 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
172 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
173 if (!CBB_add_u8(&cbb, '/'))
174 goto err;
175 if (!X509_NAME_ENTRY_add_cbb(&cbb, ne))
176 goto err;
177 }
178
179 if (!CBB_add_u8(&cbb, '\0'))
180 goto err;
181
182 if (!CBB_finish(&cbb, &line, &line_len))
183 goto err;
184
185 if (buf == NULL)
186 return line;
187
188 strlcpy(buf, line, len);
189 free(line);
190
191 return buf;
192
193 err:
194 CBB_cleanup(&cbb);
195
196 return NULL;
197}
198LCRYPTO_ALIAS(X509_NAME_oneline);
diff --git a/src/lib/libcrypto/x509/x509_ocsp.c b/src/lib/libcrypto/x509/x509_ocsp.c
deleted file mode 100644
index 6531b4c420..0000000000
--- a/src/lib/libcrypto/x509/x509_ocsp.c
+++ /dev/null
@@ -1,424 +0,0 @@
1/* $OpenBSD: x509_ocsp.c,v 1.4 2024/12/24 09:14:33 schwarze Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/opensslconf.h>
63
64#ifndef OPENSSL_NO_OCSP
65
66#include <openssl/asn1.h>
67#include <openssl/conf.h>
68#include <openssl/err.h>
69#include <openssl/ocsp.h>
70#include <openssl/x509v3.h>
71
72#include "ocsp_local.h"
73
74/* OCSP extensions and a couple of CRL entry extensions
75 */
76
77static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
78 BIO *out, int indent);
79static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
80 BIO *out, int indent);
81static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
82 int indent);
83
84static void *ocsp_nonce_new(void);
85static int i2d_ocsp_nonce(void *a, unsigned char **pp);
86static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
87static void ocsp_nonce_free(void *a);
88static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
89 BIO *out, int indent);
90
91static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
92 void *nocheck, BIO *out, int indent);
93static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
94 const char *str);
95static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
96 BIO *bp, int ind);
97
98static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_CrlID = {
99 .ext_nid = NID_id_pkix_OCSP_CrlID,
100 .ext_flags = 0,
101 .it = &OCSP_CRLID_it,
102 .ext_new = NULL,
103 .ext_free = NULL,
104 .d2i = NULL,
105 .i2d = NULL,
106 .i2s = NULL,
107 .s2i = NULL,
108 .i2v = NULL,
109 .v2i = NULL,
110 .i2r = i2r_ocsp_crlid,
111 .r2i = NULL,
112 .usr_data = NULL,
113};
114
115const X509V3_EXT_METHOD *
116x509v3_ext_method_id_pkix_OCSP_CrlID(void)
117{
118 return &x509v3_ext_id_pkix_OCSP_CrlID;
119}
120
121static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_archiveCutoff = {
122 .ext_nid = NID_id_pkix_OCSP_archiveCutoff,
123 .ext_flags = 0,
124 .it = &ASN1_GENERALIZEDTIME_it,
125 .ext_new = NULL,
126 .ext_free = NULL,
127 .d2i = NULL,
128 .i2d = NULL,
129 .i2s = NULL,
130 .s2i = NULL,
131 .i2v = NULL,
132 .v2i = NULL,
133 .i2r = i2r_ocsp_acutoff,
134 .r2i = NULL,
135 .usr_data = NULL,
136};
137
138const X509V3_EXT_METHOD *
139x509v3_ext_method_id_pkix_OCSP_archiveCutoff(void)
140{
141 return &x509v3_ext_id_pkix_OCSP_archiveCutoff;
142}
143
144static const X509V3_EXT_METHOD x509v3_ext_invalidity_date = {
145 .ext_nid = NID_invalidity_date,
146 .ext_flags = 0,
147 .it = &ASN1_GENERALIZEDTIME_it,
148 .ext_new = NULL,
149 .ext_free = NULL,
150 .d2i = NULL,
151 .i2d = NULL,
152 .i2s = NULL,
153 .s2i = NULL,
154 .i2v = NULL,
155 .v2i = NULL,
156 .i2r = i2r_ocsp_acutoff,
157 .r2i = NULL,
158 .usr_data = NULL,
159};
160
161const X509V3_EXT_METHOD *
162x509v3_ext_method_invalidity_date(void)
163{
164 return &x509v3_ext_invalidity_date;
165}
166
167static const X509V3_EXT_METHOD x509v3_ext_hold_instruction_code = {
168 .ext_nid = NID_hold_instruction_code,
169 .ext_flags = 0,
170 .it = &ASN1_OBJECT_it,
171 .ext_new = NULL,
172 .ext_free = NULL,
173 .d2i = NULL,
174 .i2d = NULL,
175 .i2s = NULL,
176 .s2i = NULL,
177 .i2v = NULL,
178 .v2i = NULL,
179 .i2r = i2r_object,
180 .r2i = NULL,
181 .usr_data = NULL,
182};
183
184const X509V3_EXT_METHOD *
185x509v3_ext_method_hold_instruction_code(void)
186{
187 return &x509v3_ext_hold_instruction_code;
188}
189
190static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_Nonce = {
191 .ext_nid = NID_id_pkix_OCSP_Nonce,
192 .ext_flags = 0,
193 .it = NULL,
194 .ext_new = ocsp_nonce_new,
195 .ext_free = ocsp_nonce_free,
196 .d2i = d2i_ocsp_nonce,
197 .i2d = i2d_ocsp_nonce,
198 .i2s = NULL,
199 .s2i = NULL,
200 .i2v = NULL,
201 .v2i = NULL,
202 .i2r = i2r_ocsp_nonce,
203 .r2i = NULL,
204 .usr_data = NULL,
205};
206
207const X509V3_EXT_METHOD *
208x509v3_ext_method_id_pkix_OCSP_Nonce(void)
209{
210 return &x509v3_ext_id_pkix_OCSP_Nonce;
211}
212
213static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_noCheck = {
214 .ext_nid = NID_id_pkix_OCSP_noCheck,
215 .ext_flags = 0,
216 .it = &ASN1_NULL_it,
217 .ext_new = NULL,
218 .ext_free = NULL,
219 .d2i = NULL,
220 .i2d = NULL,
221 .i2s = NULL,
222 .s2i = s2i_ocsp_nocheck,
223 .i2v = NULL,
224 .v2i = NULL,
225 .i2r = i2r_ocsp_nocheck,
226 .r2i = NULL,
227 .usr_data = NULL,
228};
229
230const X509V3_EXT_METHOD *
231x509v3_ext_method_id_pkix_OCSP_noCheck(void)
232{
233 return &x509v3_ext_id_pkix_OCSP_noCheck;
234}
235
236static const X509V3_EXT_METHOD x509v3_ext_id_pkix_OCSP_serviceLocator = {
237 .ext_nid = NID_id_pkix_OCSP_serviceLocator,
238 .ext_flags = 0,
239 .it = &OCSP_SERVICELOC_it,
240 .ext_new = NULL,
241 .ext_free = NULL,
242 .d2i = NULL,
243 .i2d = NULL,
244 .i2s = NULL,
245 .s2i = NULL,
246 .i2v = NULL,
247 .v2i = NULL,
248 .i2r = i2r_ocsp_serviceloc,
249 .r2i = NULL,
250 .usr_data = NULL,
251};
252
253const X509V3_EXT_METHOD *
254x509v3_ext_method_id_pkix_OCSP_serviceLocator(void)
255{
256 return &x509v3_ext_id_pkix_OCSP_serviceLocator;
257}
258
259static int
260i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind)
261{
262 OCSP_CRLID *a = in;
263 if (a->crlUrl) {
264 if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0)
265 goto err;
266 if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl))
267 goto err;
268 if (BIO_write(bp, "\n", 1) <= 0)
269 goto err;
270 }
271 if (a->crlNum) {
272 if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0)
273 goto err;
274 if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0)
275 goto err;
276 if (BIO_write(bp, "\n", 1) <= 0)
277 goto err;
278 }
279 if (a->crlTime) {
280 if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0)
281 goto err;
282 if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime))
283 goto err;
284 if (BIO_write(bp, "\n", 1) <= 0)
285 goto err;
286 }
287 return 1;
288
289err:
290 return 0;
291}
292
293static int
294i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, BIO *bp,
295 int ind)
296{
297 if (BIO_printf(bp, "%*s", ind, "") <= 0)
298 return 0;
299 if (!ASN1_GENERALIZEDTIME_print(bp, cutoff))
300 return 0;
301 return 1;
302}
303
304static int
305i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind)
306{
307 if (BIO_printf(bp, "%*s", ind, "") <= 0)
308 return 0;
309 if (i2a_ASN1_OBJECT(bp, oid) <= 0)
310 return 0;
311 return 1;
312}
313
314/* OCSP nonce. This is needs special treatment because it doesn't have
315 * an ASN1 encoding at all: it just contains arbitrary data.
316 */
317
318static void *
319ocsp_nonce_new(void)
320{
321 return ASN1_OCTET_STRING_new();
322}
323
324static int
325i2d_ocsp_nonce(void *a, unsigned char **pp)
326{
327 ASN1_OCTET_STRING *os = a;
328
329 if (pp) {
330 memcpy(*pp, os->data, os->length);
331 *pp += os->length;
332 }
333 return os->length;
334}
335
336static void *
337d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
338{
339 ASN1_OCTET_STRING *os, **pos;
340
341 pos = a;
342 if (pos == NULL || *pos == NULL) {
343 os = ASN1_OCTET_STRING_new();
344 if (os == NULL)
345 goto err;
346 } else
347 os = *pos;
348 if (ASN1_OCTET_STRING_set(os, *pp, length) == 0)
349 goto err;
350
351 *pp += length;
352
353 if (pos != NULL)
354 *pos = os;
355 return os;
356
357err:
358 if (pos == NULL || *pos != os)
359 ASN1_OCTET_STRING_free(os);
360 OCSPerror(ERR_R_MALLOC_FAILURE);
361 return NULL;
362}
363
364static void
365ocsp_nonce_free(void *a)
366{
367 ASN1_OCTET_STRING_free(a);
368}
369
370static int
371i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, BIO *out,
372 int indent)
373{
374 if (BIO_printf(out, "%*s", indent, "") <= 0)
375 return 0;
376 if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0)
377 return 0;
378 return 1;
379}
380
381/* Nocheck is just a single NULL. Don't print anything and always set it */
382
383static int
384i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, BIO *out,
385 int indent)
386{
387 return 1;
388}
389
390static void *
391s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
392 const char *str)
393{
394 return ASN1_NULL_new();
395}
396
397static int
398i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind)
399{
400 int i;
401 OCSP_SERVICELOC *a = in;
402 ACCESS_DESCRIPTION *ad;
403
404 if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0)
405 goto err;
406 if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0)
407 goto err;
408 for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) {
409 ad = sk_ACCESS_DESCRIPTION_value(a->locator, i);
410 if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0)
411 goto err;
412 if (i2a_ASN1_OBJECT(bp, ad->method) <= 0)
413 goto err;
414 if (BIO_puts(bp, " - ") <= 0)
415 goto err;
416 if (GENERAL_NAME_print(bp, ad->location) <= 0)
417 goto err;
418 }
419 return 1;
420
421err:
422 return 0;
423}
424#endif
diff --git a/src/lib/libcrypto/x509/x509_pcons.c b/src/lib/libcrypto/x509/x509_pcons.c
deleted file mode 100644
index 66dc57abf6..0000000000
--- a/src/lib/libcrypto/x509/x509_pcons.c
+++ /dev/null
@@ -1,205 +0,0 @@
1/* $OpenBSD: x509_pcons.c,v 1.6 2024/08/31 10:03:03 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2003 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
64#include <openssl/conf.h>
65#include <openssl/err.h>
66#include <openssl/x509v3.h>
67
68#include "x509_local.h"
69
70static STACK_OF(CONF_VALUE) *
71i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons,
72 STACK_OF(CONF_VALUE) *extlist);
73static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
74 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
75
76static const X509V3_EXT_METHOD x509v3_ext_policy_constraints = {
77 .ext_nid = NID_policy_constraints,
78 .ext_flags = 0,
79 .it = &POLICY_CONSTRAINTS_it,
80 .ext_new = NULL,
81 .ext_free = NULL,
82 .d2i = NULL,
83 .i2d = NULL,
84 .i2s = NULL,
85 .s2i = NULL,
86 .i2v = i2v_POLICY_CONSTRAINTS,
87 .v2i = v2i_POLICY_CONSTRAINTS,
88 .i2r = NULL,
89 .r2i = NULL,
90 .usr_data = NULL,
91};
92
93const X509V3_EXT_METHOD *
94x509v3_ext_method_policy_constraints(void)
95{
96 return &x509v3_ext_policy_constraints;
97}
98
99static const ASN1_TEMPLATE POLICY_CONSTRAINTS_seq_tt[] = {
100 {
101 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
102 .tag = 0,
103 .offset = offsetof(POLICY_CONSTRAINTS, requireExplicitPolicy),
104 .field_name = "requireExplicitPolicy",
105 .item = &ASN1_INTEGER_it,
106 },
107 {
108 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
109 .tag = 1,
110 .offset = offsetof(POLICY_CONSTRAINTS, inhibitPolicyMapping),
111 .field_name = "inhibitPolicyMapping",
112 .item = &ASN1_INTEGER_it,
113 },
114};
115
116const ASN1_ITEM POLICY_CONSTRAINTS_it = {
117 .itype = ASN1_ITYPE_SEQUENCE,
118 .utype = V_ASN1_SEQUENCE,
119 .templates = POLICY_CONSTRAINTS_seq_tt,
120 .tcount = sizeof(POLICY_CONSTRAINTS_seq_tt) / sizeof(ASN1_TEMPLATE),
121 .funcs = NULL,
122 .size = sizeof(POLICY_CONSTRAINTS),
123 .sname = "POLICY_CONSTRAINTS",
124};
125LCRYPTO_ALIAS(POLICY_CONSTRAINTS_it);
126
127
128POLICY_CONSTRAINTS *
129POLICY_CONSTRAINTS_new(void)
130{
131 return (POLICY_CONSTRAINTS*)ASN1_item_new(&POLICY_CONSTRAINTS_it);
132}
133LCRYPTO_ALIAS(POLICY_CONSTRAINTS_new);
134
135void
136POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a)
137{
138 ASN1_item_free((ASN1_VALUE *)a, &POLICY_CONSTRAINTS_it);
139}
140LCRYPTO_ALIAS(POLICY_CONSTRAINTS_free);
141
142static STACK_OF(CONF_VALUE) *
143i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
144 STACK_OF(CONF_VALUE) *extlist)
145{
146 POLICY_CONSTRAINTS *pcons = a;
147 STACK_OF(CONF_VALUE) *free_extlist = NULL;
148
149 if (extlist == NULL) {
150 if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
151 return NULL;
152 }
153
154 if (!X509V3_add_value_int("Require Explicit Policy",
155 pcons->requireExplicitPolicy, &extlist))
156 goto err;
157 if (!X509V3_add_value_int("Inhibit Policy Mapping",
158 pcons->inhibitPolicyMapping, &extlist))
159 goto err;
160
161 return extlist;
162
163 err:
164 sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
165
166 return NULL;
167}
168
169static void *
170v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
171 STACK_OF(CONF_VALUE) *values)
172{
173 POLICY_CONSTRAINTS *pcons = NULL;
174 CONF_VALUE *val;
175 int i;
176
177 if (!(pcons = POLICY_CONSTRAINTS_new())) {
178 X509V3error(ERR_R_MALLOC_FAILURE);
179 return NULL;
180 }
181 for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
182 val = sk_CONF_VALUE_value(values, i);
183 if (!strcmp(val->name, "requireExplicitPolicy")) {
184 if (!X509V3_get_value_int(val,
185 &pcons->requireExplicitPolicy)) goto err;
186 } else if (!strcmp(val->name, "inhibitPolicyMapping")) {
187 if (!X509V3_get_value_int(val,
188 &pcons->inhibitPolicyMapping)) goto err;
189 } else {
190 X509V3error(X509V3_R_INVALID_NAME);
191 X509V3_conf_err(val);
192 goto err;
193 }
194 }
195 if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
196 X509V3error(X509V3_R_ILLEGAL_EMPTY_EXTENSION);
197 goto err;
198 }
199
200 return pcons;
201
202err:
203 POLICY_CONSTRAINTS_free(pcons);
204 return NULL;
205}
diff --git a/src/lib/libcrypto/x509/x509_pku.c b/src/lib/libcrypto/x509/x509_pku.c
deleted file mode 100644
index 6753f0f733..0000000000
--- a/src/lib/libcrypto/x509/x509_pku.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/* $OpenBSD: x509_pku.c,v 1.5 2024/07/13 15:08:58 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/asn1t.h>
63#include <openssl/x509v3.h>
64
65static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
66 PKEY_USAGE_PERIOD *usage, BIO *out, int indent);
67
68static const X509V3_EXT_METHOD x509v3_ext_private_key_usage_period = {
69 .ext_nid = NID_private_key_usage_period,
70 .ext_flags = 0,
71 .it = &PKEY_USAGE_PERIOD_it,
72 .ext_new = NULL,
73 .ext_free = NULL,
74 .d2i = NULL,
75 .i2d = NULL,
76 .i2s = NULL,
77 .s2i = NULL,
78 .i2v = NULL,
79 .v2i = NULL,
80 .i2r = (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD,
81 .r2i = NULL,
82 .usr_data = NULL,
83};
84
85const X509V3_EXT_METHOD *
86x509v3_ext_method_private_key_usage_period(void)
87{
88 return &x509v3_ext_private_key_usage_period;
89}
90
91static const ASN1_TEMPLATE PKEY_USAGE_PERIOD_seq_tt[] = {
92 {
93 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
94 .tag = 0,
95 .offset = offsetof(PKEY_USAGE_PERIOD, notBefore),
96 .field_name = "notBefore",
97 .item = &ASN1_GENERALIZEDTIME_it,
98 },
99 {
100 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
101 .tag = 1,
102 .offset = offsetof(PKEY_USAGE_PERIOD, notAfter),
103 .field_name = "notAfter",
104 .item = &ASN1_GENERALIZEDTIME_it,
105 },
106};
107
108const ASN1_ITEM PKEY_USAGE_PERIOD_it = {
109 .itype = ASN1_ITYPE_SEQUENCE,
110 .utype = V_ASN1_SEQUENCE,
111 .templates = PKEY_USAGE_PERIOD_seq_tt,
112 .tcount = sizeof(PKEY_USAGE_PERIOD_seq_tt) / sizeof(ASN1_TEMPLATE),
113 .funcs = NULL,
114 .size = sizeof(PKEY_USAGE_PERIOD),
115 .sname = "PKEY_USAGE_PERIOD",
116};
117LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_it);
118
119
120PKEY_USAGE_PERIOD *
121d2i_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD **a, const unsigned char **in, long len)
122{
123 return (PKEY_USAGE_PERIOD *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
124 &PKEY_USAGE_PERIOD_it);
125}
126LCRYPTO_ALIAS(d2i_PKEY_USAGE_PERIOD);
127
128int
129i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out)
130{
131 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKEY_USAGE_PERIOD_it);
132}
133LCRYPTO_ALIAS(i2d_PKEY_USAGE_PERIOD);
134
135PKEY_USAGE_PERIOD *
136PKEY_USAGE_PERIOD_new(void)
137{
138 return (PKEY_USAGE_PERIOD *)ASN1_item_new(&PKEY_USAGE_PERIOD_it);
139}
140LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_new);
141
142void
143PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a)
144{
145 ASN1_item_free((ASN1_VALUE *)a, &PKEY_USAGE_PERIOD_it);
146}
147LCRYPTO_ALIAS(PKEY_USAGE_PERIOD_free);
148
149static int
150i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage,
151 BIO *out, int indent)
152{
153 BIO_printf(out, "%*s", indent, "");
154 if (usage->notBefore) {
155 BIO_write(out, "Not Before: ", 12);
156 ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
157 if (usage->notAfter)
158 BIO_write(out, ", ", 2);
159 }
160 if (usage->notAfter) {
161 BIO_write(out, "Not After: ", 11);
162 ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
163 }
164 return 1;
165}
diff --git a/src/lib/libcrypto/x509/x509_pmaps.c b/src/lib/libcrypto/x509/x509_pmaps.c
deleted file mode 100644
index 5039f65f2e..0000000000
--- a/src/lib/libcrypto/x509/x509_pmaps.c
+++ /dev/null
@@ -1,247 +0,0 @@
1/* $OpenBSD: x509_pmaps.c,v 1.6 2024/08/31 10:03:03 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2003 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 */
58
59
60#include <stdio.h>
61
62#include <openssl/asn1t.h>
63#include <openssl/conf.h>
64#include <openssl/err.h>
65#include <openssl/x509v3.h>
66
67#include "x509_local.h"
68
69static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
70 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
71static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(
72 const X509V3_EXT_METHOD *method, void *pmps, STACK_OF(CONF_VALUE) *extlist);
73
74static const X509V3_EXT_METHOD x509v3_ext_policy_mappings = {
75 .ext_nid = NID_policy_mappings,
76 .ext_flags = 0,
77 .it = &POLICY_MAPPINGS_it,
78 .ext_new = NULL,
79 .ext_free = NULL,
80 .d2i = NULL,
81 .i2d = NULL,
82 .i2s = NULL,
83 .s2i = NULL,
84 .i2v = i2v_POLICY_MAPPINGS,
85 .v2i = v2i_POLICY_MAPPINGS,
86 .i2r = NULL,
87 .r2i = NULL,
88 .usr_data = NULL,
89};
90
91const X509V3_EXT_METHOD *
92x509v3_ext_method_policy_mappings(void)
93{
94 return &x509v3_ext_policy_mappings;
95}
96
97static const ASN1_TEMPLATE POLICY_MAPPING_seq_tt[] = {
98 {
99 .flags = 0,
100 .tag = 0,
101 .offset = offsetof(POLICY_MAPPING, issuerDomainPolicy),
102 .field_name = "issuerDomainPolicy",
103 .item = &ASN1_OBJECT_it,
104 },
105 {
106 .flags = 0,
107 .tag = 0,
108 .offset = offsetof(POLICY_MAPPING, subjectDomainPolicy),
109 .field_name = "subjectDomainPolicy",
110 .item = &ASN1_OBJECT_it,
111 },
112};
113
114const ASN1_ITEM POLICY_MAPPING_it = {
115 .itype = ASN1_ITYPE_SEQUENCE,
116 .utype = V_ASN1_SEQUENCE,
117 .templates = POLICY_MAPPING_seq_tt,
118 .tcount = sizeof(POLICY_MAPPING_seq_tt) / sizeof(ASN1_TEMPLATE),
119 .funcs = NULL,
120 .size = sizeof(POLICY_MAPPING),
121 .sname = "POLICY_MAPPING",
122};
123LCRYPTO_ALIAS(POLICY_MAPPING_it);
124
125static const ASN1_TEMPLATE POLICY_MAPPINGS_item_tt = {
126 .flags = ASN1_TFLG_SEQUENCE_OF,
127 .tag = 0,
128 .offset = 0,
129 .field_name = "POLICY_MAPPINGS",
130 .item = &POLICY_MAPPING_it,
131};
132
133const ASN1_ITEM POLICY_MAPPINGS_it = {
134 .itype = ASN1_ITYPE_PRIMITIVE,
135 .utype = -1,
136 .templates = &POLICY_MAPPINGS_item_tt,
137 .tcount = 0,
138 .funcs = NULL,
139 .size = 0,
140 .sname = "POLICY_MAPPINGS",
141};
142LCRYPTO_ALIAS(POLICY_MAPPINGS_it);
143
144
145POLICY_MAPPING *
146POLICY_MAPPING_new(void)
147{
148 return (POLICY_MAPPING*)ASN1_item_new(&POLICY_MAPPING_it);
149}
150LCRYPTO_ALIAS(POLICY_MAPPING_new);
151
152void
153POLICY_MAPPING_free(POLICY_MAPPING *a)
154{
155 ASN1_item_free((ASN1_VALUE *)a, &POLICY_MAPPING_it);
156}
157LCRYPTO_ALIAS(POLICY_MAPPING_free);
158
159static STACK_OF(CONF_VALUE) *
160i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, void *a,
161 STACK_OF(CONF_VALUE) *extlist)
162{
163 STACK_OF(CONF_VALUE) *free_extlist = NULL;
164 POLICY_MAPPINGS *pmaps = a;
165 POLICY_MAPPING *pmap;
166 char issuer[80], subject[80];
167 int i;
168
169 if (extlist == NULL) {
170 if ((free_extlist = extlist = sk_CONF_VALUE_new_null()) == NULL)
171 return NULL;
172 }
173
174 for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
175 if ((pmap = sk_POLICY_MAPPING_value(pmaps, i)) == NULL)
176 goto err;
177 if (!i2t_ASN1_OBJECT(issuer, sizeof issuer,
178 pmap->issuerDomainPolicy))
179 goto err;
180 if (!i2t_ASN1_OBJECT(subject, sizeof subject,
181 pmap->subjectDomainPolicy))
182 goto err;
183 if (!X509V3_add_value(issuer, subject, &extlist))
184 goto err;
185 }
186
187 return extlist;
188
189 err:
190 sk_CONF_VALUE_pop_free(free_extlist, X509V3_conf_free);
191
192 return NULL;
193}
194
195static void *
196v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
197 STACK_OF(CONF_VALUE) *nval)
198{
199 POLICY_MAPPINGS *pmaps = NULL;
200 POLICY_MAPPING *pmap = NULL;
201 ASN1_OBJECT *obj1 = NULL, *obj2 = NULL;
202 CONF_VALUE *val;
203 int i, rc;
204
205 if (!(pmaps = sk_POLICY_MAPPING_new_null())) {
206 X509V3error(ERR_R_MALLOC_FAILURE);
207 return NULL;
208 }
209
210 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
211 val = sk_CONF_VALUE_value(nval, i);
212 if (!val->value || !val->name) {
213 rc = X509V3_R_INVALID_OBJECT_IDENTIFIER;
214 goto err;
215 }
216 obj1 = OBJ_txt2obj(val->name, 0);
217 obj2 = OBJ_txt2obj(val->value, 0);
218 if (!obj1 || !obj2) {
219 rc = X509V3_R_INVALID_OBJECT_IDENTIFIER;
220 goto err;
221 }
222 pmap = POLICY_MAPPING_new();
223 if (!pmap) {
224 rc = ERR_R_MALLOC_FAILURE;
225 goto err;
226 }
227 pmap->issuerDomainPolicy = obj1;
228 pmap->subjectDomainPolicy = obj2;
229 obj1 = obj2 = NULL;
230 if (sk_POLICY_MAPPING_push(pmaps, pmap) == 0) {
231 rc = ERR_R_MALLOC_FAILURE;
232 goto err;
233 }
234 pmap = NULL;
235 }
236 return pmaps;
237
238err:
239 sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
240 X509V3error(rc);
241 if (rc == X509V3_R_INVALID_OBJECT_IDENTIFIER)
242 X509V3_conf_err(val);
243 ASN1_OBJECT_free(obj1);
244 ASN1_OBJECT_free(obj2);
245 POLICY_MAPPING_free(pmap);
246 return NULL;
247}
diff --git a/src/lib/libcrypto/x509/x509_policy.c b/src/lib/libcrypto/x509/x509_policy.c
deleted file mode 100644
index d93760755d..0000000000
--- a/src/lib/libcrypto/x509/x509_policy.c
+++ /dev/null
@@ -1,1018 +0,0 @@
1/* $OpenBSD: x509_policy.c,v 1.31 2025/03/28 13:11:57 tb Exp $ */
2/*
3 * Copyright (c) 2022, Google Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <string.h>
19
20#include <openssl/err.h>
21#include <openssl/objects.h>
22#include <openssl/stack.h>
23#include <openssl/x509.h>
24#include <openssl/x509v3.h>
25
26#include "stack_local.h"
27#include "x509_internal.h"
28#include "x509_local.h"
29
30/* XXX move to proper place */
31#define X509_R_INVALID_POLICY_EXTENSION 201
32
33/*
34 * This file computes the X.509 policy tree, as described in RFC 5280,
35 * section 6.1 and RFC 9618. It differs in that:
36 *
37 * (1) It does not track "qualifier_set". This is not needed as it is not
38 * output by this implementation.
39 *
40 * (2) It builds a directed acyclic graph, rather than a tree. When a given
41 * policy matches multiple parents, RFC 5280 makes a separate node for
42 * each parent. This representation condenses them into one node with
43 * multiple parents. Thus we refer to this structure as a "policy graph",
44 * rather than a "policy tree".
45 *
46 * (3) "expected_policy_set" is not tracked explicitly and built temporarily
47 * as part of building the graph.
48 *
49 * (4) anyPolicy nodes are not tracked explicitly.
50 *
51 * (5) Some pruning steps are deferred to when policies are evaluated, as a
52 * reachability pass.
53 */
54
55/*
56 * An X509_POLICY_NODE is a node in the policy graph. It corresponds to a node
57 * from RFC 5280, section 6.1.2, step (a), but we store some fields differently.
58 */
59typedef struct x509_policy_node_st {
60 /* policy is the "valid_policy" field from RFC 5280. */
61 ASN1_OBJECT *policy;
62
63 /*
64 * parent_policies, if non-empty, is the list of "valid_policy" values
65 * for all nodes which are a parent of this node. In this case, no entry
66 * in this list will be anyPolicy. This list is in no particular order
67 * and may contain duplicates if the corresponding certificate had
68 * duplicate mappings.
69 *
70 * If empty, this node has a single parent, anyPolicy. The node is then
71 * a root policies, and is in authorities-constrained-policy-set if it
72 * has a path to a leaf node.
73 *
74 * Note it is not possible for a policy to have both anyPolicy and a
75 * concrete policy as a parent. Section 6.1.3, step (d.1.ii) only runs
76 * if there was no match in step (d.1.i). We do not need to represent a
77 * parent list of, say, {anyPolicy, OID1, OID2}.
78 */
79 STACK_OF(ASN1_OBJECT) *parent_policies;
80
81 /*
82 * mapped is one if this node matches a policy mapping in the
83 * certificate and zero otherwise.
84 */
85 int mapped;
86
87 /*
88 * reachable is one if this node is reachable from some valid policy in
89 * the end-entity certificate. It is computed during |has_explicit_policy|.
90 */
91 int reachable;
92} X509_POLICY_NODE;
93
94DECLARE_STACK_OF(X509_POLICY_NODE)
95
96#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp))
97#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
98#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
99#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
100#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
101#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
102#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
103#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
104#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
105#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
106#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
107#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
108#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
109#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
110#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
111#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
112#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
113#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
114#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
115#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
116
117/*
118 * An X509_POLICY_LEVEL is the collection of nodes at the same depth in the
119 * policy graph. This structure can also be used to represent a level's
120 * "expected_policy_set" values. See |process_policy_mappings|.
121 */
122typedef struct x509_policy_level_st {
123 /*
124 * nodes is the list of nodes at this depth, except for the anyPolicy
125 * node, if any. This list is sorted by policy OID for efficient lookup.
126 */
127 STACK_OF(X509_POLICY_NODE) *nodes;
128
129 /*
130 * has_any_policy is one if there is an anyPolicy node at this depth,
131 * and zero otherwise.
132 */
133 int has_any_policy;
134} X509_POLICY_LEVEL;
135
136DECLARE_STACK_OF(X509_POLICY_LEVEL)
137
138#define sk_X509_POLICY_LEVEL_new(cmp) SKM_sk_new(X509_POLICY_LEVEL, (cmp))
139#define sk_X509_POLICY_LEVEL_new_null() SKM_sk_new_null(X509_POLICY_LEVEL)
140#define sk_X509_POLICY_LEVEL_free(st) SKM_sk_free(X509_POLICY_LEVEL, (st))
141#define sk_X509_POLICY_LEVEL_num(st) SKM_sk_num(X509_POLICY_LEVEL, (st))
142#define sk_X509_POLICY_LEVEL_value(st, i) SKM_sk_value(X509_POLICY_LEVEL, (st), (i))
143#define sk_X509_POLICY_LEVEL_set(st, i, val) SKM_sk_set(X509_POLICY_LEVEL, (st), (i), (val))
144#define sk_X509_POLICY_LEVEL_zero(st) SKM_sk_zero(X509_POLICY_LEVEL, (st))
145#define sk_X509_POLICY_LEVEL_push(st, val) SKM_sk_push(X509_POLICY_LEVEL, (st), (val))
146#define sk_X509_POLICY_LEVEL_unshift(st, val) SKM_sk_unshift(X509_POLICY_LEVEL, (st), (val))
147#define sk_X509_POLICY_LEVEL_find(st, val) SKM_sk_find(X509_POLICY_LEVEL, (st), (val))
148#define sk_X509_POLICY_LEVEL_delete(st, i) SKM_sk_delete(X509_POLICY_LEVEL, (st), (i))
149#define sk_X509_POLICY_LEVEL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_LEVEL, (st), (ptr))
150#define sk_X509_POLICY_LEVEL_insert(st, val, i) SKM_sk_insert(X509_POLICY_LEVEL, (st), (val), (i))
151#define sk_X509_POLICY_LEVEL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_LEVEL, (st), (cmp))
152#define sk_X509_POLICY_LEVEL_dup(st) SKM_sk_dup(X509_POLICY_LEVEL, st)
153#define sk_X509_POLICY_LEVEL_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_LEVEL, (st), (free_func))
154#define sk_X509_POLICY_LEVEL_shift(st) SKM_sk_shift(X509_POLICY_LEVEL, (st))
155#define sk_X509_POLICY_LEVEL_pop(st) SKM_sk_pop(X509_POLICY_LEVEL, (st))
156#define sk_X509_POLICY_LEVEL_sort(st) SKM_sk_sort(X509_POLICY_LEVEL, (st))
157#define sk_X509_POLICY_LEVEL_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_LEVEL, (st))
158
159/*
160 * Don't look Ethel, but you would really not want to look if we did
161 * this the OpenSSL way either, and we are not using this boringsslism
162 * anywhere else. Callers should ensure that the stack in data is sorted.
163 */
164void
165sk_X509_POLICY_NODE_delete_if(STACK_OF(X509_POLICY_NODE) *nodes,
166 int (*delete_if)(X509_POLICY_NODE *, void *), void *data)
167{
168 _STACK *sk = (_STACK *)nodes;
169 X509_POLICY_NODE *node;
170 int new_num = 0;
171 int i;
172
173 for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
174 node = sk_X509_POLICY_NODE_value(nodes, i);
175 if (!delete_if(node, data))
176 sk->data[new_num++] = (char *)node;
177 }
178 sk->num = new_num;
179}
180
181static int
182is_any_policy(const ASN1_OBJECT *obj)
183{
184 return OBJ_obj2nid(obj) == NID_any_policy;
185}
186
187static void
188x509_policy_node_free(X509_POLICY_NODE *node)
189{
190 if (node == NULL)
191 return;
192
193 ASN1_OBJECT_free(node->policy);
194 sk_ASN1_OBJECT_pop_free(node->parent_policies, ASN1_OBJECT_free);
195 free(node);
196}
197
198static X509_POLICY_NODE *
199x509_policy_node_new(const ASN1_OBJECT *policy)
200{
201 X509_POLICY_NODE *node = NULL;
202
203 if (is_any_policy(policy))
204 goto err;
205 if ((node = calloc(1, sizeof(*node))) == NULL)
206 goto err;
207 if ((node->policy = OBJ_dup(policy)) == NULL)
208 goto err;
209 if ((node->parent_policies = sk_ASN1_OBJECT_new_null()) == NULL)
210 goto err;
211
212 return node;
213
214 err:
215 x509_policy_node_free(node);
216 return NULL;
217}
218
219static int
220x509_policy_node_cmp(const X509_POLICY_NODE *const *a,
221 const X509_POLICY_NODE *const *b)
222{
223 return OBJ_cmp((*a)->policy, (*b)->policy);
224}
225
226static void
227x509_policy_level_free(X509_POLICY_LEVEL *level)
228{
229 if (level == NULL)
230 return;
231
232 sk_X509_POLICY_NODE_pop_free(level->nodes, x509_policy_node_free);
233 free(level);
234}
235
236static X509_POLICY_LEVEL *
237x509_policy_level_new(void)
238{
239 X509_POLICY_LEVEL *level;
240
241 if ((level = calloc(1, sizeof(*level))) == NULL)
242 goto err;
243 level->nodes = sk_X509_POLICY_NODE_new(x509_policy_node_cmp);
244 if (level->nodes == NULL)
245 goto err;
246
247 return level;
248
249 err:
250 x509_policy_level_free(level);
251 return NULL;
252}
253
254static int
255x509_policy_level_is_empty(const X509_POLICY_LEVEL *level)
256{
257 if (level->has_any_policy)
258 return 0;
259
260 return sk_X509_POLICY_NODE_num(level->nodes) == 0;
261}
262
263static void
264x509_policy_level_clear(X509_POLICY_LEVEL *level)
265{
266 X509_POLICY_NODE *node;
267 int i;
268
269 level->has_any_policy = 0;
270 for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
271 node = sk_X509_POLICY_NODE_value(level->nodes, i);
272 x509_policy_node_free(node);
273 }
274 sk_X509_POLICY_NODE_zero(level->nodes);
275}
276
277/*
278 * x509_policy_level_find returns the node in |level| corresponding to |policy|,
279 * or NULL if none exists. Callers should ensure that level->nodes is sorted
280 * to avoid the cost of sorting it in sk_find().
281 */
282static X509_POLICY_NODE *
283x509_policy_level_find(X509_POLICY_LEVEL *level, const ASN1_OBJECT *policy)
284{
285 X509_POLICY_NODE node;
286 node.policy = (ASN1_OBJECT *)policy;
287 int idx;
288
289 if ((idx = sk_X509_POLICY_NODE_find(level->nodes, &node)) < 0)
290 return NULL;
291 return sk_X509_POLICY_NODE_value(level->nodes, idx);
292}
293
294/*
295 * x509_policy_level_add_nodes adds the nodes in |nodes| to |level|. It returns
296 * one on success and zero on error. No policy in |nodes| may already be present
297 * in |level|. This function modifies |nodes| to avoid making a copy, but the
298 * caller is still responsible for releasing |nodes| itself.
299 *
300 * This function is used to add nodes to |level| in bulk, and avoid resorting
301 * |level| after each addition.
302 */
303static int
304x509_policy_level_add_nodes(X509_POLICY_LEVEL *level,
305 STACK_OF(X509_POLICY_NODE) *nodes)
306{
307 int i;
308
309 for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
310 X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(nodes, i);
311 if (!sk_X509_POLICY_NODE_push(level->nodes, node))
312 return 0;
313 sk_X509_POLICY_NODE_set(nodes, i, NULL);
314 }
315 sk_X509_POLICY_NODE_sort(level->nodes);
316
317 return 1;
318}
319
320static int
321policyinfo_cmp(const POLICYINFO *const *a,
322 const POLICYINFO *const *b)
323{
324 return OBJ_cmp((*a)->policyid, (*b)->policyid);
325}
326
327static int
328delete_if_not_in_policies(X509_POLICY_NODE *node, void *data)
329{
330 const CERTIFICATEPOLICIES *policies = data;
331 POLICYINFO info;
332 info.policyid = node->policy;
333
334 if (sk_POLICYINFO_find(policies, &info) >= 0)
335 return 0;
336 x509_policy_node_free(node);
337 return 1;
338}
339
340/*
341 * process_certificate_policies updates |level| to incorporate |x509|'s
342 * certificate policies extension. This implements steps (d) and (e) of RFC
343 * 5280, section 6.1.3. |level| must contain the previous level's
344 * "expected_policy_set" information. For all but the top-most level, this is
345 * the output of |process_policy_mappings|. |any_policy_allowed| specifies
346 * whether anyPolicy is allowed or inhibited, taking into account the exception
347 * for self-issued certificates.
348 */
349static int
350process_certificate_policies(const X509 *x509, X509_POLICY_LEVEL *level,
351 int any_policy_allowed)
352{
353 STACK_OF(X509_POLICY_NODE) *new_nodes = NULL;
354 CERTIFICATEPOLICIES *policies;
355 const POLICYINFO *policy;
356 X509_POLICY_NODE *node;
357 int cert_has_any_policy, critical, i, previous_level_has_any_policy;
358 int ret = 0;
359
360 policies = X509_get_ext_d2i(x509, NID_certificate_policies, &critical,
361 NULL);
362 if (policies == NULL) {
363 if (critical != -1)
364 return 0; /* Syntax error in the extension. */
365
366 /* RFC 5280, section 6.1.3, step (e). */
367 x509_policy_level_clear(level);
368 return 1;
369 }
370
371 /*
372 * certificatePolicies may not be empty. See RFC 5280, section 4.2.1.4.
373 * TODO(https://crbug.com/boringssl/443): Move this check into the parser.
374 */
375 if (sk_POLICYINFO_num(policies) == 0) {
376 X509error(X509_R_INVALID_POLICY_EXTENSION);
377 goto err;
378 }
379
380 (void)sk_POLICYINFO_set_cmp_func(policies, policyinfo_cmp);
381 sk_POLICYINFO_sort(policies);
382 cert_has_any_policy = 0;
383 for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
384 policy = sk_POLICYINFO_value(policies, i);
385 if (is_any_policy(policy->policyid))
386 cert_has_any_policy = 1;
387 if (i > 0 &&
388 OBJ_cmp(sk_POLICYINFO_value(policies, i - 1)->policyid,
389 policy->policyid) == 0) {
390 /*
391 * Per RFC 5280, section 4.2.1.4, |policies| may not
392 * have duplicates.
393 */
394 X509error(X509_R_INVALID_POLICY_EXTENSION);
395 goto err;
396 }
397 }
398
399 /*
400 * This does the same thing as RFC 5280, section 6.1.3, step (d),
401 * though in a slightly different order. |level| currently contains
402 * "expected_policy_set" values of the previous level.
403 * See |process_policy_mappings| for details.
404 */
405 previous_level_has_any_policy = level->has_any_policy;
406
407 /*
408 * First, we handle steps (d.1.i) and (d.2). The net effect of these
409 * two steps is to intersect |level| with |policies|, ignoring
410 * anyPolicy if it is inhibited.
411 */
412 if (!cert_has_any_policy || !any_policy_allowed) {
413 if (!sk_POLICYINFO_is_sorted(policies))
414 goto err;
415 sk_X509_POLICY_NODE_delete_if(level->nodes,
416 delete_if_not_in_policies, policies);
417 level->has_any_policy = 0;
418 }
419
420 /*
421 * Step (d.1.ii) may attach new nodes to the previous level's anyPolicy
422 * node.
423 */
424 if (previous_level_has_any_policy) {
425 new_nodes = sk_X509_POLICY_NODE_new_null();
426 if (new_nodes == NULL)
427 goto err;
428 for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
429 policy = sk_POLICYINFO_value(policies, i);
430 /*
431 * Though we've reordered the steps slightly, |policy|
432 * is in |level| if and only if it would have been a
433 * match in step (d.1.ii).
434 */
435 if (is_any_policy(policy->policyid))
436 continue;
437 if (!sk_X509_POLICY_NODE_is_sorted(level->nodes))
438 goto err;
439 if (x509_policy_level_find(level, policy->policyid) != NULL)
440 continue;
441 node = x509_policy_node_new(policy->policyid);
442 if (node == NULL ||
443 !sk_X509_POLICY_NODE_push(new_nodes, node)) {
444 x509_policy_node_free(node);
445 goto err;
446 }
447 }
448 if (!x509_policy_level_add_nodes(level, new_nodes))
449 goto err;
450 }
451
452 ret = 1;
453
454err:
455 sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free);
456 CERTIFICATEPOLICIES_free(policies);
457 return ret;
458}
459
460static int
461compare_issuer_policy(const POLICY_MAPPING *const *a,
462 const POLICY_MAPPING *const *b)
463{
464 return OBJ_cmp((*a)->issuerDomainPolicy, (*b)->issuerDomainPolicy);
465}
466
467static int
468compare_subject_policy(const POLICY_MAPPING *const *a,
469 const POLICY_MAPPING *const *b)
470{
471 return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy);
472}
473
474static int
475delete_if_mapped(X509_POLICY_NODE *node, void *data)
476{
477 const POLICY_MAPPINGS *mappings = data;
478 POLICY_MAPPING mapping;
479 mapping.issuerDomainPolicy = node->policy;
480 if (sk_POLICY_MAPPING_find(mappings, &mapping) < 0)
481 return 0;
482 x509_policy_node_free(node);
483 return 1;
484}
485
486/*
487 * process_policy_mappings processes the policy mappings extension of |cert|,
488 * whose corresponding graph level is |level|. |mapping_allowed| specifies
489 * whether policy mapping is inhibited at this point. On success, it returns an
490 * |X509_POLICY_LEVEL| containing the "expected_policy_set" for |level|. On
491 * error, it returns NULL. This implements steps (a) and (b) of RFC 5280,
492 * section 6.1.4.
493 *
494 * We represent the "expected_policy_set" as an |X509_POLICY_LEVEL|.
495 * |has_any_policy| indicates whether there is an anyPolicy node with
496 * "expected_policy_set" of {anyPolicy}. If a node with policy oid P1 contains
497 * P2 in its "expected_policy_set", the level will contain a node of policy P2
498 * with P1 in |parent_policies|.
499 *
500 * This is equivalent to the |X509_POLICY_LEVEL| that would result if the next
501 * certificate contained anyPolicy. |process_certificate_policies| will filter
502 * this result down to compute the actual level.
503 */
504static X509_POLICY_LEVEL *
505process_policy_mappings(const X509 *cert,
506 X509_POLICY_LEVEL *level,
507 int mapping_allowed)
508{
509 STACK_OF(X509_POLICY_NODE) *new_nodes = NULL;
510 POLICY_MAPPINGS *mappings;
511 const ASN1_OBJECT *last_policy;
512 POLICY_MAPPING *mapping;
513 X509_POLICY_LEVEL *next = NULL;
514 X509_POLICY_NODE *node;
515 int critical, i;
516 int ok = 0;
517
518 mappings = X509_get_ext_d2i(cert, NID_policy_mappings, &critical, NULL);
519 if (mappings == NULL && critical != -1) {
520 /* Syntax error in the policy mappings extension. */
521 goto err;
522 }
523
524 if (mappings != NULL) {
525 /*
526 * PolicyMappings may not be empty. See RFC 5280, section 4.2.1.5.
527 * TODO(https://crbug.com/boringssl/443): Move this check into
528 * the parser.
529 */
530 if (sk_POLICY_MAPPING_num(mappings) == 0) {
531 X509error(X509_R_INVALID_POLICY_EXTENSION);
532 goto err;
533 }
534
535 /* RFC 5280, section 6.1.4, step (a). */
536 for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) {
537 mapping = sk_POLICY_MAPPING_value(mappings, i);
538 if (is_any_policy(mapping->issuerDomainPolicy) ||
539 is_any_policy(mapping->subjectDomainPolicy))
540 goto err;
541 }
542
543 /* Sort to group by issuerDomainPolicy. */
544 (void)sk_POLICY_MAPPING_set_cmp_func(mappings,
545 compare_issuer_policy);
546 sk_POLICY_MAPPING_sort(mappings);
547
548 if (mapping_allowed) {
549 /*
550 * Mark nodes as mapped, and add any nodes to |level|
551 * which may be needed as part of RFC 5280,
552 * section 6.1.4, step (b.1).
553 */
554 new_nodes = sk_X509_POLICY_NODE_new_null();
555 if (new_nodes == NULL)
556 goto err;
557 last_policy = NULL;
558 for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) {
559 mapping = sk_POLICY_MAPPING_value(mappings, i);
560 /*
561 * There may be multiple mappings with the same
562 * |issuerDomainPolicy|.
563 */
564 if (last_policy != NULL &&
565 OBJ_cmp(mapping->issuerDomainPolicy,
566 last_policy) == 0)
567 continue;
568 last_policy = mapping->issuerDomainPolicy;
569
570 if (!sk_X509_POLICY_NODE_is_sorted(level->nodes))
571 goto err;
572 node = x509_policy_level_find(level,
573 mapping->issuerDomainPolicy);
574 if (node == NULL) {
575 if (!level->has_any_policy)
576 continue;
577 node = x509_policy_node_new(
578 mapping->issuerDomainPolicy);
579 if (node == NULL ||
580 !sk_X509_POLICY_NODE_push(new_nodes,
581 node)) {
582 x509_policy_node_free(node);
583 goto err;
584 }
585 }
586 node->mapped = 1;
587 }
588 if (!x509_policy_level_add_nodes(level, new_nodes))
589 goto err;
590 } else {
591 /*
592 * RFC 5280, section 6.1.4, step (b.2). If mapping is
593 * inhibited, delete all mapped nodes.
594 */
595 if (!sk_POLICY_MAPPING_is_sorted(mappings))
596 goto err;
597 sk_X509_POLICY_NODE_delete_if(level->nodes,
598 delete_if_mapped, mappings);
599 sk_POLICY_MAPPING_pop_free(mappings,
600 POLICY_MAPPING_free);
601 mappings = NULL;
602 }
603 }
604
605 /*
606 * If a node was not mapped, it retains the original "explicit_policy_set"
607 * value, itself. Add those to |mappings|.
608 */
609 if (mappings == NULL) {
610 mappings = sk_POLICY_MAPPING_new_null();
611 if (mappings == NULL)
612 goto err;
613 }
614 for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
615 node = sk_X509_POLICY_NODE_value(level->nodes, i);
616 if (!node->mapped) {
617 mapping = POLICY_MAPPING_new();
618 if (mapping == NULL)
619 goto err;
620 mapping->issuerDomainPolicy = OBJ_dup(node->policy);
621 mapping->subjectDomainPolicy = OBJ_dup(node->policy);
622 if (mapping->issuerDomainPolicy == NULL ||
623 mapping->subjectDomainPolicy == NULL ||
624 !sk_POLICY_MAPPING_push(mappings, mapping)) {
625 POLICY_MAPPING_free(mapping);
626 goto err;
627 }
628 }
629 }
630
631 /* Sort to group by subjectDomainPolicy. */
632 (void)sk_POLICY_MAPPING_set_cmp_func(mappings, compare_subject_policy);
633 sk_POLICY_MAPPING_sort(mappings);
634
635 /* Convert |mappings| to our "expected_policy_set" representation. */
636 next = x509_policy_level_new();
637 if (next == NULL)
638 goto err;
639 next->has_any_policy = level->has_any_policy;
640
641 X509_POLICY_NODE *last_node = NULL;
642 for (i = 0; i < sk_POLICY_MAPPING_num(mappings); i++) {
643 mapping = sk_POLICY_MAPPING_value(mappings, i);
644 /*
645 * Skip mappings where |issuerDomainPolicy| does not appear in
646 * the graph.
647 */
648 if (!level->has_any_policy) {
649 if (!sk_X509_POLICY_NODE_is_sorted(level->nodes))
650 goto err;
651 if (x509_policy_level_find(level,
652 mapping->issuerDomainPolicy) == NULL)
653 continue;
654 }
655
656 if (last_node == NULL ||
657 OBJ_cmp(last_node->policy, mapping->subjectDomainPolicy) !=
658 0) {
659 last_node = x509_policy_node_new(
660 mapping->subjectDomainPolicy);
661 if (last_node == NULL ||
662 !sk_X509_POLICY_NODE_push(next->nodes, last_node)) {
663 x509_policy_node_free(last_node);
664 goto err;
665 }
666 }
667
668 if (!sk_ASN1_OBJECT_push(last_node->parent_policies,
669 mapping->issuerDomainPolicy))
670 goto err;
671 mapping->issuerDomainPolicy = NULL;
672 }
673
674 sk_X509_POLICY_NODE_sort(next->nodes);
675 ok = 1;
676
677err:
678 if (!ok) {
679 x509_policy_level_free(next);
680 next = NULL;
681 }
682
683 sk_POLICY_MAPPING_pop_free(mappings, POLICY_MAPPING_free);
684 sk_X509_POLICY_NODE_pop_free(new_nodes, x509_policy_node_free);
685 return next;
686}
687
688/*
689 * apply_skip_certs, if |skip_certs| is non-NULL, sets |*value| to the minimum
690 * of its current value and |skip_certs|. It returns one on success and zero if
691 * |skip_certs| is negative.
692 */
693static int
694apply_skip_certs(const ASN1_INTEGER *skip_certs, size_t *value)
695{
696 if (skip_certs == NULL)
697 return 1;
698
699 /* TODO(https://crbug.com/boringssl/443): Move this check into the parser. */
700 if (skip_certs->type & V_ASN1_NEG) {
701 X509error(X509_R_INVALID_POLICY_EXTENSION);
702 return 0;
703 }
704
705 /* If |skip_certs| does not fit in |uint64_t|, it must exceed |*value|. */
706 uint64_t u64;
707 if (ASN1_INTEGER_get_uint64(&u64, skip_certs) && u64 < *value)
708 *value = (size_t)u64;
709 ERR_clear_error();
710 return 1;
711}
712
713/*
714 * process_policy_constraints updates |*explicit_policy|, |*policy_mapping|, and
715 * |*inhibit_any_policy| according to |x509|'s policy constraints and inhibit
716 * anyPolicy extensions. It returns one on success and zero on error. This
717 * implements steps (i) and (j) of RFC 5280, section 6.1.4.
718 */
719static int
720process_policy_constraints(const X509 *x509, size_t *explicit_policy,
721 size_t *policy_mapping,
722 size_t *inhibit_any_policy)
723{
724 ASN1_INTEGER *inhibit_any_policy_ext;
725 POLICY_CONSTRAINTS *constraints;
726 int critical;
727 int ok = 0;
728
729 constraints = X509_get_ext_d2i(x509, NID_policy_constraints, &critical,
730 NULL);
731 if (constraints == NULL && critical != -1)
732 return 0;
733 if (constraints != NULL) {
734 if (constraints->requireExplicitPolicy == NULL &&
735 constraints->inhibitPolicyMapping == NULL) {
736 /*
737 * Per RFC 5280, section 4.2.1.11, at least one of the
738 * fields must be
739 */
740 X509error(X509_R_INVALID_POLICY_EXTENSION);
741 POLICY_CONSTRAINTS_free(constraints);
742 return 0;
743 }
744 ok = apply_skip_certs(constraints->requireExplicitPolicy,
745 explicit_policy) &&
746 apply_skip_certs(constraints->inhibitPolicyMapping,
747 policy_mapping);
748 POLICY_CONSTRAINTS_free(constraints);
749 if (!ok)
750 return 0;
751 }
752
753 inhibit_any_policy_ext = X509_get_ext_d2i(x509, NID_inhibit_any_policy,
754 &critical, NULL);
755 if (inhibit_any_policy_ext == NULL && critical != -1)
756 return 0;
757 ok = apply_skip_certs(inhibit_any_policy_ext, inhibit_any_policy);
758 ASN1_INTEGER_free(inhibit_any_policy_ext);
759 return ok;
760}
761
762/*
763 * has_explicit_policy returns one if the set of authority-space policy OIDs
764 * |levels| has some non-empty intersection with |user_policies|, and zero
765 * otherwise. This mirrors the logic in RFC 5280, section 6.1.5, step (g). This
766 * function modifies |levels| and should only be called at the end of policy
767 * evaluation.
768 */
769static int
770has_explicit_policy(STACK_OF(X509_POLICY_LEVEL) *levels,
771 const STACK_OF(ASN1_OBJECT) *user_policies)
772{
773 X509_POLICY_LEVEL *level, *prev;
774 X509_POLICY_NODE *node, *parent;
775 int num_levels, user_has_any_policy;
776 int i, j, k;
777
778 if (!sk_ASN1_OBJECT_is_sorted(user_policies))
779 return 0;
780
781 /* Step (g.i). If the policy graph is empty, the intersection is empty. */
782 num_levels = sk_X509_POLICY_LEVEL_num(levels);
783 level = sk_X509_POLICY_LEVEL_value(levels, num_levels - 1);
784 if (x509_policy_level_is_empty(level))
785 return 0;
786
787 /*
788 * If |user_policies| is empty, we interpret it as having a single
789 * anyPolicy value. The caller may also have supplied anyPolicy
790 * explicitly.
791 */
792 user_has_any_policy = sk_ASN1_OBJECT_num(user_policies) <= 0;
793 for (i = 0; i < sk_ASN1_OBJECT_num(user_policies); i++) {
794 if (is_any_policy(sk_ASN1_OBJECT_value(user_policies, i))) {
795 user_has_any_policy = 1;
796 break;
797 }
798 }
799
800 /*
801 * Step (g.ii). If the policy graph is not empty and the user set
802 * contains anyPolicy, the intersection is the entire (non-empty) graph.
803 */
804 if (user_has_any_policy)
805 return 1;
806
807 /*
808 * Step (g.iii) does not delete anyPolicy nodes, so if the graph has
809 * anyPolicy, some explicit policy will survive. The actual intersection
810 * may synthesize some nodes in step (g.iii.3), but we do not return the
811 * policy list itself, so we skip actually computing this.
812 */
813 if (level->has_any_policy)
814 return 1;
815
816 /*
817 * We defer pruning the tree, so as we look for nodes with parent
818 * anyPolicy, step (g.iii.1), we must limit to nodes reachable from the
819 * bottommost level. Start by marking each of those nodes as reachable.
820 */
821 for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++)
822 sk_X509_POLICY_NODE_value(level->nodes, i)->reachable = 1;
823
824 for (i = num_levels - 1; i >= 0; i--) {
825 level = sk_X509_POLICY_LEVEL_value(levels, i);
826 for (j = 0; j < sk_X509_POLICY_NODE_num(level->nodes); j++) {
827 node = sk_X509_POLICY_NODE_value(level->nodes, j);
828 if (!node->reachable)
829 continue;
830 if (sk_ASN1_OBJECT_num(node->parent_policies) == 0) {
831 /*
832 * |node|'s parent is anyPolicy and is part of
833 * "valid_policy_node_set". If it exists in
834 * |user_policies|, the intersection is
835 * non-empty and we * can return immediately.
836 */
837 if (sk_ASN1_OBJECT_find(user_policies,
838 node->policy) >= 0)
839 return 1;
840 } else if (i > 0) {
841 int num_parent_policies =
842 sk_ASN1_OBJECT_num(node->parent_policies);
843 /*
844 * |node|'s parents are concrete policies. Mark
845 * the parents reachable, to be inspected by the
846 * next loop iteration.
847 */
848 prev = sk_X509_POLICY_LEVEL_value(levels, i - 1);
849 for (k = 0; k < num_parent_policies; k++) {
850 if (!sk_X509_POLICY_NODE_is_sorted(prev->nodes))
851 return 0;
852 parent = x509_policy_level_find(prev,
853 sk_ASN1_OBJECT_value(node->parent_policies,
854 k));
855 if (parent != NULL)
856 parent->reachable = 1;
857 }
858 }
859 }
860 }
861
862 return 0;
863}
864
865static int
866asn1_object_cmp(const ASN1_OBJECT *const *a, const ASN1_OBJECT *const *b)
867{
868 return OBJ_cmp(*a, *b);
869}
870
871int
872X509_policy_check(const STACK_OF(X509) *certs,
873 const STACK_OF(ASN1_OBJECT) *user_policies,
874 unsigned long flags, X509 **out_current_cert)
875{
876 *out_current_cert = NULL;
877 int ret = X509_V_ERR_OUT_OF_MEM;
878 X509 *cert;
879 X509_POLICY_LEVEL *level = NULL;
880 X509_POLICY_LEVEL *current_level;
881 STACK_OF(X509_POLICY_LEVEL) *levels = NULL;
882 STACK_OF(ASN1_OBJECT) *user_policies_sorted = NULL;
883 int num_certs = sk_X509_num(certs);
884 int is_self_issued, any_policy_allowed;
885 int i;
886
887 /* Skip policy checking if the chain is just the trust anchor. */
888 if (num_certs <= 1)
889 return X509_V_OK;
890
891 /* See RFC 5280, section 6.1.2, steps (d) through (f). */
892 size_t explicit_policy =
893 (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : num_certs + 1;
894 size_t inhibit_any_policy =
895 (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : num_certs + 1;
896 size_t policy_mapping =
897 (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : num_certs + 1;
898
899 levels = sk_X509_POLICY_LEVEL_new_null();
900 if (levels == NULL)
901 goto err;
902
903 for (i = num_certs - 2; i >= 0; i--) {
904 cert = sk_X509_value(certs, i);
905 if (!x509v3_cache_extensions(cert))
906 goto err;
907 is_self_issued = (cert->ex_flags & EXFLAG_SI) != 0;
908
909 if (level == NULL) {
910 if (i != num_certs - 2)
911 goto err;
912 level = x509_policy_level_new();
913 if (level == NULL)
914 goto err;
915 level->has_any_policy = 1;
916 }
917
918 /*
919 * RFC 5280, section 6.1.3, steps (d) and (e). |any_policy_allowed|
920 * is computed as in step (d.2).
921 */
922 any_policy_allowed =
923 inhibit_any_policy > 0 || (i > 0 && is_self_issued);
924 if (!process_certificate_policies(cert, level,
925 any_policy_allowed)) {
926 ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
927 *out_current_cert = cert;
928 goto err;
929 }
930
931 /* RFC 5280, section 6.1.3, step (f). */
932 if (explicit_policy == 0 && x509_policy_level_is_empty(level)) {
933 ret = X509_V_ERR_NO_EXPLICIT_POLICY;
934 goto err;
935 }
936
937 /* Insert into the list. */
938 if (!sk_X509_POLICY_LEVEL_push(levels, level))
939 goto err;
940 current_level = level;
941 level = NULL;
942
943 /*
944 * If this is not the leaf certificate, we go to section 6.1.4.
945 * If it is the leaf certificate, we go to section 6.1.5 instead.
946 */
947 if (i != 0) {
948 /* RFC 5280, section 6.1.4, steps (a) and (b). */
949 level = process_policy_mappings(cert, current_level,
950 policy_mapping > 0);
951 if (level == NULL) {
952 ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
953 *out_current_cert = cert;
954 goto err;
955 }
956 }
957
958 /*
959 * RFC 5280, section 6.1.4, step (h-j) for non-leaves, and
960 * section 6.1.5, step (a-b) for leaves. In the leaf case,
961 * RFC 5280 says only to update |explicit_policy|, but
962 * |policy_mapping| and |inhibit_any_policy| are no
963 * longer read at this point, so we use the same process.
964 */
965 if (i == 0 || !is_self_issued) {
966 if (explicit_policy > 0)
967 explicit_policy--;
968 if (policy_mapping > 0)
969 policy_mapping--;
970 if (inhibit_any_policy > 0)
971 inhibit_any_policy--;
972 }
973 if (!process_policy_constraints(cert, &explicit_policy,
974 &policy_mapping, &inhibit_any_policy)) {
975 ret = X509_V_ERR_INVALID_POLICY_EXTENSION;
976 *out_current_cert = cert;
977 goto err;
978 }
979 }
980
981 /*
982 * RFC 5280, section 6.1.5, step (g). We do not output the policy set,
983 * so it is only necessary to check if the user-constrained-policy-set
984 * is not empty.
985 */
986 if (explicit_policy == 0) {
987 /*
988 * Build a sorted copy of |user_policies| for more efficient
989 * lookup.
990 */
991 if (user_policies != NULL) {
992 user_policies_sorted = sk_ASN1_OBJECT_dup(
993 user_policies);
994 if (user_policies_sorted == NULL)
995 goto err;
996 (void)sk_ASN1_OBJECT_set_cmp_func(user_policies_sorted,
997 asn1_object_cmp);
998 sk_ASN1_OBJECT_sort(user_policies_sorted);
999 }
1000
1001 if (!has_explicit_policy(levels, user_policies_sorted)) {
1002 ret = X509_V_ERR_NO_EXPLICIT_POLICY;
1003 goto err;
1004 }
1005 }
1006
1007 ret = X509_V_OK;
1008
1009err:
1010 x509_policy_level_free(level);
1011 /*
1012 * |user_policies_sorted|'s contents are owned by |user_policies|, so
1013 * we do not use |sk_ASN1_OBJECT_pop_free|.
1014 */
1015 sk_ASN1_OBJECT_free(user_policies_sorted);
1016 sk_X509_POLICY_LEVEL_pop_free(levels, x509_policy_level_free);
1017 return ret;
1018}
diff --git a/src/lib/libcrypto/x509/x509_prn.c b/src/lib/libcrypto/x509/x509_prn.c
deleted file mode 100644
index 3bf7c803e5..0000000000
--- a/src/lib/libcrypto/x509/x509_prn.c
+++ /dev/null
@@ -1,231 +0,0 @@
1/* $OpenBSD: x509_prn.c,v 1.6 2023/05/08 05:30:38 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58/* X509 v3 extension utilities */
59
60#include <stdio.h>
61
62#include <openssl/conf.h>
63#include <openssl/x509v3.h>
64
65#include "x509_local.h"
66
67/* Extension printing routines */
68
69static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
70 int indent, int supported);
71
72/* Print out a name+value stack */
73
74void
75X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml)
76{
77 int i;
78 CONF_VALUE *nval;
79
80 if (!val)
81 return;
82 if (!ml || !sk_CONF_VALUE_num(val)) {
83 BIO_printf(out, "%*s", indent, "");
84 if (!sk_CONF_VALUE_num(val))
85 BIO_puts(out, "<EMPTY>\n");
86 }
87 for (i = 0; i < sk_CONF_VALUE_num(val); i++) {
88 if (ml)
89 BIO_printf(out, "%*s", indent, "");
90 else if (i > 0) BIO_printf(out, ", ");
91 nval = sk_CONF_VALUE_value(val, i);
92 if (!nval->name)
93 BIO_puts(out, nval->value);
94 else if (!nval->value)
95 BIO_puts(out, nval->name);
96 else
97 BIO_printf(out, "%s:%s", nval->name, nval->value);
98 if (ml)
99 BIO_puts(out, "\n");
100 }
101}
102LCRYPTO_ALIAS(X509V3_EXT_val_prn);
103
104/* Main routine: print out a general extension */
105
106int
107X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent)
108{
109 void *ext_str = NULL;
110 char *value = NULL;
111 const unsigned char *p;
112 const X509V3_EXT_METHOD *method;
113 STACK_OF(CONF_VALUE) *nval = NULL;
114 int ok = 1;
115
116 if (!(method = X509V3_EXT_get(ext)))
117 return unknown_ext_print(out, ext, flag, indent, 0);
118 p = ext->value->data;
119 if (method->it)
120 ext_str = ASN1_item_d2i(NULL, &p, ext->value->length,
121 method->it);
122 else
123 ext_str = method->d2i(NULL, &p, ext->value->length);
124
125 if (!ext_str)
126 return unknown_ext_print(out, ext, flag, indent, 1);
127
128 if (method->i2s) {
129 if (!(value = method->i2s(method, ext_str))) {
130 ok = 0;
131 goto err;
132 }
133 BIO_printf(out, "%*s%s", indent, "", value);
134 } else if (method->i2v) {
135 if (!(nval = method->i2v(method, ext_str, NULL))) {
136 ok = 0;
137 goto err;
138 }
139 X509V3_EXT_val_prn(out, nval, indent,
140 method->ext_flags & X509V3_EXT_MULTILINE);
141 } else if (method->i2r) {
142 if (!method->i2r(method, ext_str, out, indent))
143 ok = 0;
144 } else
145 ok = 0;
146
147err:
148 sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
149 free(value);
150 if (method->it)
151 ASN1_item_free(ext_str, method->it);
152 else
153 method->ext_free(ext_str);
154 return ok;
155}
156LCRYPTO_ALIAS(X509V3_EXT_print);
157
158int
159X509V3_extensions_print(BIO *bp, const char *title,
160 const STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent)
161{
162 int i, j;
163
164 if (sk_X509_EXTENSION_num(exts) <= 0)
165 return 1;
166
167 if (title) {
168 BIO_printf(bp, "%*s%s:\n",indent, "", title);
169 indent += 4;
170 }
171
172 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
173 ASN1_OBJECT *obj;
174 X509_EXTENSION *ex;
175 ex = sk_X509_EXTENSION_value(exts, i);
176 if (indent && BIO_printf(bp, "%*s",indent, "") <= 0)
177 return 0;
178 obj = X509_EXTENSION_get_object(ex);
179 i2a_ASN1_OBJECT(bp, obj);
180 j = X509_EXTENSION_get_critical(ex);
181 if (BIO_printf(bp, ":%s\n", j ? " critical" : "") <= 0)
182 return 0;
183 if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) {
184 BIO_printf(bp, "%*s", indent + 4, "");
185 ASN1_STRING_print(bp, ex->value);
186 }
187 if (BIO_write(bp, "\n",1) <= 0)
188 return 0;
189 }
190 return 1;
191}
192LCRYPTO_ALIAS(X509V3_extensions_print);
193
194static int
195unknown_ext_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
196 int indent, int supported)
197{
198 switch (flag & X509V3_EXT_UNKNOWN_MASK) {
199 case X509V3_EXT_DEFAULT:
200 return 0;
201 case X509V3_EXT_ERROR_UNKNOWN:
202 if (supported)
203 BIO_printf(out, "%*s<Parse Error>", indent, "");
204 else
205 BIO_printf(out, "%*s<Not Supported>", indent, "");
206 return 1;
207 case X509V3_EXT_PARSE_UNKNOWN:
208 return ASN1_parse_dump(out,
209 ext->value->data, ext->value->length, indent, -1);
210 case X509V3_EXT_DUMP_UNKNOWN:
211 return BIO_dump_indent(out, (char *)ext->value->data,
212 ext->value->length, indent);
213 default:
214 return 1;
215 }
216}
217
218
219int
220X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
221{
222 BIO *bio_tmp;
223 int ret;
224
225 if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE)))
226 return 0;
227 ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
228 BIO_free(bio_tmp);
229 return ret;
230}
231LCRYPTO_ALIAS(X509V3_EXT_print_fp);
diff --git a/src/lib/libcrypto/x509/x509_purp.c b/src/lib/libcrypto/x509/x509_purp.c
deleted file mode 100644
index 619a4b890a..0000000000
--- a/src/lib/libcrypto/x509/x509_purp.c
+++ /dev/null
@@ -1,930 +0,0 @@
1/* $OpenBSD: x509_purp.c,v 1.43 2024/07/12 18:15:10 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/opensslconf.h>
63
64#include <openssl/err.h>
65#include <openssl/x509v3.h>
66#include <openssl/x509_vfy.h>
67
68#include "x509_internal.h"
69#include "x509_local.h"
70
71struct x509_purpose_st {
72 int purpose;
73 int trust; /* Default trust ID */
74 int flags;
75 int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int);
76 char *name;
77 char *sname;
78 void *usr_data;
79} /* X509_PURPOSE */;
80
81#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
82#define ku_reject(x, usage) \
83 (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
84#define xku_reject(x, usage) \
85 (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
86#define ns_reject(x, usage) \
87 (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
88
89static int check_ssl_ca(const X509 *x);
90static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
91 int ca);
92static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
93 int ca);
94static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
95 int ca);
96static int purpose_smime(const X509 *x, int ca);
97static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
98 int ca);
99static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
100 int ca);
101static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
102 int ca);
103static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
104 int ca);
105static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
106static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
107
108static const X509_PURPOSE xstandard[] = {
109 {
110 .purpose = X509_PURPOSE_SSL_CLIENT,
111 .trust = X509_TRUST_SSL_CLIENT,
112 .check_purpose = check_purpose_ssl_client,
113 .name = "SSL client",
114 .sname = "sslclient",
115 },
116 {
117 .purpose = X509_PURPOSE_SSL_SERVER,
118 .trust = X509_TRUST_SSL_SERVER,
119 .check_purpose = check_purpose_ssl_server,
120 .name = "SSL server",
121 .sname = "sslserver",
122 },
123 {
124 .purpose = X509_PURPOSE_NS_SSL_SERVER,
125 .trust = X509_TRUST_SSL_SERVER,
126 .check_purpose = check_purpose_ns_ssl_server,
127 .name = "Netscape SSL server",
128 .sname = "nssslserver",
129 },
130 {
131 .purpose = X509_PURPOSE_SMIME_SIGN,
132 .trust = X509_TRUST_EMAIL,
133 .check_purpose = check_purpose_smime_sign,
134 .name = "S/MIME signing",
135 .sname = "smimesign",
136 },
137 {
138 .purpose = X509_PURPOSE_SMIME_ENCRYPT,
139 .trust = X509_TRUST_EMAIL,
140 .check_purpose = check_purpose_smime_encrypt,
141 .name = "S/MIME encryption",
142 .sname = "smimeencrypt",
143 },
144 {
145 .purpose = X509_PURPOSE_CRL_SIGN,
146 .trust = X509_TRUST_COMPAT,
147 .check_purpose = check_purpose_crl_sign,
148 .name = "CRL signing",
149 .sname = "crlsign",
150 },
151 {
152 .purpose = X509_PURPOSE_ANY,
153 .trust = X509_TRUST_ACCEPT_ALL,
154 .check_purpose = no_check,
155 .name = "Any Purpose",
156 .sname = "any",
157 },
158 {
159 .purpose = X509_PURPOSE_OCSP_HELPER,
160 .trust = X509_TRUST_COMPAT,
161 .check_purpose = ocsp_helper,
162 .name = "OCSP helper",
163 .sname = "ocsphelper",
164 },
165 {
166 .purpose = X509_PURPOSE_TIMESTAMP_SIGN,
167 .trust = X509_TRUST_TSA,
168 .check_purpose = check_purpose_timestamp_sign,
169 .name = "Time Stamp signing",
170 .sname = "timestampsign",
171 },
172};
173
174#define X509_PURPOSE_COUNT (sizeof(xstandard) / sizeof(xstandard[0]))
175
176/* As much as I'd like to make X509_check_purpose use a "const" X509*
177 * I really can't because it does recalculate hashes and do other non-const
178 * things. */
179int
180X509_check_purpose(X509 *x, int id, int ca)
181{
182 int idx;
183 const X509_PURPOSE *pt;
184
185 if (!x509v3_cache_extensions(x))
186 return -1;
187
188 if (id == -1)
189 return 1;
190
191 if ((idx = X509_PURPOSE_get_by_id(id)) == -1)
192 return -1;
193 if ((pt = X509_PURPOSE_get0(idx)) == NULL)
194 return -1;
195
196 return pt->check_purpose(pt, x, ca);
197}
198LCRYPTO_ALIAS(X509_check_purpose);
199
200int
201X509_PURPOSE_get_count(void)
202{
203 return X509_PURPOSE_COUNT;
204}
205LCRYPTO_ALIAS(X509_PURPOSE_get_count);
206
207const X509_PURPOSE *
208X509_PURPOSE_get0(int idx)
209{
210 if (idx < 0 || (size_t)idx >= X509_PURPOSE_COUNT)
211 return NULL;
212
213 return &xstandard[idx];
214}
215LCRYPTO_ALIAS(X509_PURPOSE_get0);
216
217int
218X509_PURPOSE_get_by_sname(const char *sname)
219{
220 int i;
221 const X509_PURPOSE *xptmp;
222
223 for (i = 0; i < X509_PURPOSE_get_count(); i++) {
224 xptmp = X509_PURPOSE_get0(i);
225 if (!strcmp(xptmp->sname, sname))
226 return i;
227 }
228 return -1;
229}
230LCRYPTO_ALIAS(X509_PURPOSE_get_by_sname);
231
232int
233X509_PURPOSE_get_by_id(int purpose)
234{
235 /*
236 * Ensure the purpose identifier is between MIN and MAX inclusive.
237 * If so, translate it to an index into the xstandard[] table.
238 */
239 if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX)
240 return -1;
241
242 return purpose - X509_PURPOSE_MIN;
243}
244
245int
246X509_PURPOSE_get_id(const X509_PURPOSE *xp)
247{
248 return xp->purpose;
249}
250LCRYPTO_ALIAS(X509_PURPOSE_get_id);
251
252const char *
253X509_PURPOSE_get0_name(const X509_PURPOSE *xp)
254{
255 return xp->name;
256}
257LCRYPTO_ALIAS(X509_PURPOSE_get0_name);
258
259const char *
260X509_PURPOSE_get0_sname(const X509_PURPOSE *xp)
261{
262 return xp->sname;
263}
264LCRYPTO_ALIAS(X509_PURPOSE_get0_sname);
265
266int
267X509_PURPOSE_get_trust(const X509_PURPOSE *xp)
268{
269 return xp->trust;
270}
271
272/*
273 * List of NIDs of extensions supported by the verifier. If an extension
274 * is critical and doesn't appear in this list, then the certificate will
275 * normally be rejected.
276 */
277int
278X509_supported_extension(X509_EXTENSION *ext)
279{
280 switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext))) {
281 case NID_basic_constraints:
282 case NID_certificate_policies:
283 case NID_ext_key_usage:
284 case NID_inhibit_any_policy:
285 case NID_key_usage:
286 case NID_name_constraints:
287 case NID_netscape_cert_type:
288 case NID_policy_constraints:
289 case NID_policy_mappings:
290#ifndef OPENSSL_NO_RFC3779
291 case NID_sbgp_ipAddrBlock:
292 case NID_sbgp_autonomousSysNum:
293#endif
294 case NID_subject_alt_name:
295 return 1;
296 default:
297 return 0;
298 }
299}
300LCRYPTO_ALIAS(X509_supported_extension);
301
302static void
303setup_dp(X509 *x, DIST_POINT *dp)
304{
305 X509_NAME *iname = NULL;
306 int i;
307
308 if (dp->reasons) {
309 if (dp->reasons->length > 0)
310 dp->dp_reasons = dp->reasons->data[0];
311 if (dp->reasons->length > 1)
312 dp->dp_reasons |= (dp->reasons->data[1] << 8);
313 dp->dp_reasons &= CRLDP_ALL_REASONS;
314 } else
315 dp->dp_reasons = CRLDP_ALL_REASONS;
316 if (!dp->distpoint || (dp->distpoint->type != 1))
317 return;
318 for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
319 GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
320 if (gen->type == GEN_DIRNAME) {
321 iname = gen->d.directoryName;
322 break;
323 }
324 }
325 if (!iname)
326 iname = X509_get_issuer_name(x);
327
328 DIST_POINT_set_dpname(dp->distpoint, iname);
329}
330
331static void
332setup_crldp(X509 *x)
333{
334 int i;
335
336 x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL);
337 if (x->crldp == NULL && i != -1) {
338 x->ex_flags |= EXFLAG_INVALID;
339 return;
340 }
341
342 for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
343 setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
344}
345
346static int
347x509_extension_oid_cmp(const X509_EXTENSION *const *a,
348 const X509_EXTENSION *const *b)
349{
350 return OBJ_cmp((*a)->object, (*b)->object);
351}
352
353static int
354x509_extension_oids_are_unique(X509 *x509)
355{
356 STACK_OF(X509_EXTENSION) *exts = NULL;
357 const X509_EXTENSION *prev_ext, *curr_ext;
358 int i;
359 int ret = 0;
360
361 if (X509_get_ext_count(x509) <= 1)
362 goto done;
363
364 if ((exts = sk_X509_EXTENSION_dup(x509->cert_info->extensions)) == NULL)
365 goto err;
366
367 (void)sk_X509_EXTENSION_set_cmp_func(exts, x509_extension_oid_cmp);
368 sk_X509_EXTENSION_sort(exts);
369
370 prev_ext = sk_X509_EXTENSION_value(exts, 0);
371 for (i = 1; i < sk_X509_EXTENSION_num(exts); i++) {
372 curr_ext = sk_X509_EXTENSION_value(exts, i);
373 if (x509_extension_oid_cmp(&prev_ext, &curr_ext) == 0)
374 goto err;
375 prev_ext = curr_ext;
376 }
377
378 done:
379 ret = 1;
380
381 err:
382 sk_X509_EXTENSION_free(exts);
383
384 return ret;
385}
386
387static void
388x509v3_cache_extensions_internal(X509 *x)
389{
390 BASIC_CONSTRAINTS *bs;
391 ASN1_BIT_STRING *usage;
392 ASN1_BIT_STRING *ns;
393 EXTENDED_KEY_USAGE *extusage;
394 X509_EXTENSION *ex;
395 long version;
396 int i;
397
398 if (x->ex_flags & EXFLAG_SET)
399 return;
400
401 /*
402 * XXX - this should really only set EXFLAG_INVALID if extensions are
403 * invalid. However, the X509_digest() failure matches OpenSSL/BoringSSL
404 * behavior and the version checks are at least vaguely related to
405 * extensions.
406 */
407
408 if (!X509_digest(x, X509_CERT_HASH_EVP, x->hash, NULL))
409 x->ex_flags |= EXFLAG_INVALID;
410
411 version = X509_get_version(x);
412 if (version < 0 || version > 2)
413 x->ex_flags |= EXFLAG_INVALID;
414 if (version == 0) {
415 x->ex_flags |= EXFLAG_V1;
416 /* UIDs may only appear in v2 or v3 certs */
417 if (x->cert_info->issuerUID != NULL ||
418 x->cert_info->subjectUID != NULL)
419 x->ex_flags |= EXFLAG_INVALID;
420 }
421 if (version != 2 && X509_get_ext_count(x) != 0)
422 x->ex_flags |= EXFLAG_INVALID;
423
424 /* Handle basic constraints */
425 if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL))) {
426 if (bs->ca)
427 x->ex_flags |= EXFLAG_CA;
428 if (bs->pathlen) {
429 if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) ||
430 !bs->ca) {
431 x->ex_flags |= EXFLAG_INVALID;
432 x->ex_pathlen = 0;
433 } else
434 x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
435 } else
436 x->ex_pathlen = -1;
437 BASIC_CONSTRAINTS_free(bs);
438 x->ex_flags |= EXFLAG_BCONS;
439 } else if (i != -1) {
440 x->ex_flags |= EXFLAG_INVALID;
441 }
442
443 /* Handle key usage */
444 if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL))) {
445 if (usage->length > 0) {
446 x->ex_kusage = usage->data[0];
447 if (usage->length > 1)
448 x->ex_kusage |= usage->data[1] << 8;
449 } else
450 x->ex_kusage = 0;
451 x->ex_flags |= EXFLAG_KUSAGE;
452 ASN1_BIT_STRING_free(usage);
453 } else if (i != -1) {
454 x->ex_flags |= EXFLAG_INVALID;
455 }
456
457 x->ex_xkusage = 0;
458 if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL))) {
459 x->ex_flags |= EXFLAG_XKUSAGE;
460 for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
461 switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
462 case NID_server_auth:
463 x->ex_xkusage |= XKU_SSL_SERVER;
464 break;
465
466 case NID_client_auth:
467 x->ex_xkusage |= XKU_SSL_CLIENT;
468 break;
469
470 case NID_email_protect:
471 x->ex_xkusage |= XKU_SMIME;
472 break;
473
474 case NID_code_sign:
475 x->ex_xkusage |= XKU_CODE_SIGN;
476 break;
477
478 case NID_ms_sgc:
479 case NID_ns_sgc:
480 x->ex_xkusage |= XKU_SGC;
481 break;
482
483 case NID_OCSP_sign:
484 x->ex_xkusage |= XKU_OCSP_SIGN;
485 break;
486
487 case NID_time_stamp:
488 x->ex_xkusage |= XKU_TIMESTAMP;
489 break;
490
491 case NID_dvcs:
492 x->ex_xkusage |= XKU_DVCS;
493 break;
494
495 case NID_anyExtendedKeyUsage:
496 x->ex_xkusage |= XKU_ANYEKU;
497 break;
498 }
499 }
500 sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
501 } else if (i != -1) {
502 x->ex_flags |= EXFLAG_INVALID;
503 }
504
505 if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &i, NULL))) {
506 if (ns->length > 0)
507 x->ex_nscert = ns->data[0];
508 else
509 x->ex_nscert = 0;
510 x->ex_flags |= EXFLAG_NSCERT;
511 ASN1_BIT_STRING_free(ns);
512 } else if (i != -1) {
513 x->ex_flags |= EXFLAG_INVALID;
514 }
515
516 x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &i, NULL);
517 if (x->skid == NULL && i != -1)
518 x->ex_flags |= EXFLAG_INVALID;
519 x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &i, NULL);
520 if (x->akid == NULL && i != -1)
521 x->ex_flags |= EXFLAG_INVALID;
522
523 /* Does subject name match issuer? */
524 if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
525 x->ex_flags |= EXFLAG_SI;
526 /* If SKID matches AKID also indicate self signed. */
527 if (X509_check_akid(x, x->akid) == X509_V_OK &&
528 !ku_reject(x, KU_KEY_CERT_SIGN))
529 x->ex_flags |= EXFLAG_SS;
530 }
531
532 x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &i, NULL);
533 if (x->altname == NULL && i != -1)
534 x->ex_flags |= EXFLAG_INVALID;
535 x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
536 if (!x->nc && (i != -1))
537 x->ex_flags |= EXFLAG_INVALID;
538 setup_crldp(x);
539
540#ifndef OPENSSL_NO_RFC3779
541 x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL);
542 if (x->rfc3779_addr == NULL && i != -1)
543 x->ex_flags |= EXFLAG_INVALID;
544 if (!X509v3_addr_is_canonical(x->rfc3779_addr))
545 x->ex_flags |= EXFLAG_INVALID;
546 x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, &i, NULL);
547 if (x->rfc3779_asid == NULL && i != -1)
548 x->ex_flags |= EXFLAG_INVALID;
549 if (!X509v3_asid_is_canonical(x->rfc3779_asid))
550 x->ex_flags |= EXFLAG_INVALID;
551#endif
552
553 for (i = 0; i < X509_get_ext_count(x); i++) {
554 ex = X509_get_ext(x, i);
555 if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) ==
556 NID_freshest_crl)
557 x->ex_flags |= EXFLAG_FRESHEST;
558 if (!X509_EXTENSION_get_critical(ex))
559 continue;
560 if (!X509_supported_extension(ex)) {
561 x->ex_flags |= EXFLAG_CRITICAL;
562 break;
563 }
564 }
565
566 if (!x509_extension_oids_are_unique(x))
567 x->ex_flags |= EXFLAG_INVALID;
568
569 x->ex_flags |= EXFLAG_SET;
570}
571
572int
573x509v3_cache_extensions(X509 *x)
574{
575 if ((x->ex_flags & EXFLAG_SET) == 0) {
576 CRYPTO_w_lock(CRYPTO_LOCK_X509);
577 x509v3_cache_extensions_internal(x);
578 CRYPTO_w_unlock(CRYPTO_LOCK_X509);
579 }
580
581 return (x->ex_flags & EXFLAG_INVALID) == 0;
582}
583
584/* CA checks common to all purposes
585 * return codes:
586 * 0 not a CA
587 * 1 is a CA
588 * 2 basicConstraints absent so "maybe" a CA
589 * 3 basicConstraints absent but self signed V1.
590 * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
591 */
592
593static int
594check_ca(const X509 *x)
595{
596 /* keyUsage if present should allow cert signing */
597 if (ku_reject(x, KU_KEY_CERT_SIGN))
598 return 0;
599 if (x->ex_flags & EXFLAG_BCONS) {
600 if (x->ex_flags & EXFLAG_CA)
601 return 1;
602 /* If basicConstraints says not a CA then say so */
603 else
604 return 0;
605 } else {
606 /* we support V1 roots for... uh, I don't really know why. */
607 if ((x->ex_flags & V1_ROOT) == V1_ROOT)
608 return 3;
609 /* If key usage present it must have certSign so tolerate it */
610 else if (x->ex_flags & EXFLAG_KUSAGE)
611 return 4;
612 /* Older certificates could have Netscape-specific CA types */
613 else if (x->ex_flags & EXFLAG_NSCERT &&
614 x->ex_nscert & NS_ANY_CA)
615 return 5;
616 /* can this still be regarded a CA certificate? I doubt it */
617 return 0;
618 }
619}
620
621int
622X509_check_ca(X509 *x)
623{
624 x509v3_cache_extensions(x);
625
626 return check_ca(x);
627}
628LCRYPTO_ALIAS(X509_check_ca);
629
630/* Check SSL CA: common checks for SSL client and server */
631static int
632check_ssl_ca(const X509 *x)
633{
634 int ca_ret;
635
636 ca_ret = check_ca(x);
637 if (!ca_ret)
638 return 0;
639 /* check nsCertType if present */
640 if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA)
641 return ca_ret;
642 else
643 return 0;
644}
645
646static int
647check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
648{
649 if (xku_reject(x, XKU_SSL_CLIENT))
650 return 0;
651 if (ca)
652 return check_ssl_ca(x);
653 /* We need to do digital signatures with it */
654 if (ku_reject(x, KU_DIGITAL_SIGNATURE))
655 return 0;
656 /* nsCertType if present should allow SSL client use */
657 if (ns_reject(x, NS_SSL_CLIENT))
658 return 0;
659 return 1;
660}
661
662static int
663check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
664{
665 if (xku_reject(x, XKU_SSL_SERVER|XKU_SGC))
666 return 0;
667 if (ca)
668 return check_ssl_ca(x);
669
670 if (ns_reject(x, NS_SSL_SERVER))
671 return 0;
672 /* Now as for keyUsage: we'll at least need to sign OR encipher */
673 if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT))
674 return 0;
675
676 return 1;
677}
678
679static int
680check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
681{
682 int ret;
683
684 ret = check_purpose_ssl_server(xp, x, ca);
685 if (!ret || ca)
686 return ret;
687 /* We need to encipher or Netscape complains */
688 if (ku_reject(x, KU_KEY_ENCIPHERMENT))
689 return 0;
690 return ret;
691}
692
693/* common S/MIME checks */
694static int
695purpose_smime(const X509 *x, int ca)
696{
697 if (xku_reject(x, XKU_SMIME))
698 return 0;
699 if (ca) {
700 int ca_ret;
701 ca_ret = check_ca(x);
702 if (!ca_ret)
703 return 0;
704 /* check nsCertType if present */
705 if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA)
706 return ca_ret;
707 else
708 return 0;
709 }
710 if (x->ex_flags & EXFLAG_NSCERT) {
711 if (x->ex_nscert & NS_SMIME)
712 return 1;
713 /* Workaround for some buggy certificates */
714 if (x->ex_nscert & NS_SSL_CLIENT)
715 return 2;
716 return 0;
717 }
718 return 1;
719}
720
721static int
722check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
723{
724 int ret;
725
726 ret = purpose_smime(x, ca);
727 if (!ret || ca)
728 return ret;
729 if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION))
730 return 0;
731 return ret;
732}
733
734static int
735check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
736{
737 int ret;
738
739 ret = purpose_smime(x, ca);
740 if (!ret || ca)
741 return ret;
742 if (ku_reject(x, KU_KEY_ENCIPHERMENT))
743 return 0;
744 return ret;
745}
746
747static int
748check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
749{
750 if (ca) {
751 int ca_ret;
752 if ((ca_ret = check_ca(x)) != 2)
753 return ca_ret;
754 else
755 return 0;
756 }
757 if (ku_reject(x, KU_CRL_SIGN))
758 return 0;
759 return 1;
760}
761
762/* OCSP helper: this is *not* a full OCSP check. It just checks that
763 * each CA is valid. Additional checks must be made on the chain.
764 */
765static int
766ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
767{
768 /* Must be a valid CA. Should we really support the "I don't know"
769 value (2)? */
770 if (ca)
771 return check_ca(x);
772 /* leaf certificate is checked in OCSP_verify() */
773 return 1;
774}
775
776static int
777check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
778{
779 int i_ext;
780
781 /* If ca is true we must return if this is a valid CA certificate. */
782 if (ca)
783 return check_ca(x);
784
785 /*
786 * Check the optional key usage field:
787 * if Key Usage is present, it must be one of digitalSignature
788 * and/or nonRepudiation (other values are not consistent and shall
789 * be rejected).
790 */
791 if ((x->ex_flags & EXFLAG_KUSAGE) &&
792 ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
793 !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
794 return 0;
795
796 /* Only time stamp key usage is permitted and it's required. */
797 if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
798 return 0;
799
800 /* Extended Key Usage MUST be critical */
801 i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
802 if (i_ext >= 0) {
803 X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
804 if (!X509_EXTENSION_get_critical(ext))
805 return 0;
806 }
807
808 return 1;
809}
810
811static int
812no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
813{
814 return 1;
815}
816
817/* Various checks to see if one certificate issued the second.
818 * This can be used to prune a set of possible issuer certificates
819 * which have been looked up using some simple method such as by
820 * subject name.
821 * These are:
822 * 1. Check issuer_name(subject) == subject_name(issuer)
823 * 2. If akid(subject) exists check it matches issuer
824 * 3. If key_usage(issuer) exists check it supports certificate signing
825 * returns 0 for OK, positive for reason for mismatch, reasons match
826 * codes for X509_verify_cert()
827 */
828
829int
830X509_check_issued(X509 *issuer, X509 *subject)
831{
832 if (X509_NAME_cmp(X509_get_subject_name(issuer),
833 X509_get_issuer_name(subject)))
834 return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
835
836 if (!x509v3_cache_extensions(issuer))
837 return X509_V_ERR_UNSPECIFIED;
838 if (!x509v3_cache_extensions(subject))
839 return X509_V_ERR_UNSPECIFIED;
840
841 if (subject->akid) {
842 int ret = X509_check_akid(issuer, subject->akid);
843 if (ret != X509_V_OK)
844 return ret;
845 }
846
847 if (ku_reject(issuer, KU_KEY_CERT_SIGN))
848 return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
849 return X509_V_OK;
850}
851LCRYPTO_ALIAS(X509_check_issued);
852
853int
854X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
855{
856 if (!akid)
857 return X509_V_OK;
858
859 /* Check key ids (if present) */
860 if (akid->keyid && issuer->skid &&
861 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid))
862 return X509_V_ERR_AKID_SKID_MISMATCH;
863 /* Check serial number */
864 if (akid->serial &&
865 ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
866 return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
867 /* Check issuer name */
868 if (akid->issuer) {
869 /* Ugh, for some peculiar reason AKID includes
870 * SEQUENCE OF GeneralName. So look for a DirName.
871 * There may be more than one but we only take any
872 * notice of the first.
873 */
874 GENERAL_NAMES *gens;
875 GENERAL_NAME *gen;
876 X509_NAME *nm = NULL;
877 int i;
878 gens = akid->issuer;
879 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
880 gen = sk_GENERAL_NAME_value(gens, i);
881 if (gen->type == GEN_DIRNAME) {
882 nm = gen->d.dirn;
883 break;
884 }
885 }
886 if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
887 return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
888 }
889 return X509_V_OK;
890}
891LCRYPTO_ALIAS(X509_check_akid);
892
893uint32_t
894X509_get_extension_flags(X509 *x)
895{
896 /* Call for side-effect of computing hash and caching extensions */
897 if (X509_check_purpose(x, -1, -1) != 1)
898 return EXFLAG_INVALID;
899
900 return x->ex_flags;
901}
902LCRYPTO_ALIAS(X509_get_extension_flags);
903
904uint32_t
905X509_get_key_usage(X509 *x)
906{
907 /* Call for side-effect of computing hash and caching extensions */
908 if (X509_check_purpose(x, -1, -1) != 1)
909 return 0;
910
911 if (x->ex_flags & EXFLAG_KUSAGE)
912 return x->ex_kusage;
913
914 return UINT32_MAX;
915}
916LCRYPTO_ALIAS(X509_get_key_usage);
917
918uint32_t
919X509_get_extended_key_usage(X509 *x)
920{
921 /* Call for side-effect of computing hash and caching extensions */
922 if (X509_check_purpose(x, -1, -1) != 1)
923 return 0;
924
925 if (x->ex_flags & EXFLAG_XKUSAGE)
926 return x->ex_xkusage;
927
928 return UINT32_MAX;
929}
930LCRYPTO_ALIAS(X509_get_extended_key_usage);
diff --git a/src/lib/libcrypto/x509/x509_r2x.c b/src/lib/libcrypto/x509/x509_r2x.c
deleted file mode 100644
index 39b392259b..0000000000
--- a/src/lib/libcrypto/x509/x509_r2x.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/* $OpenBSD: x509_r2x.c,v 1.17 2023/04/25 09:46:36 job Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/bn.h>
63#include <openssl/buffer.h>
64#include <openssl/err.h>
65#include <openssl/evp.h>
66#include <openssl/objects.h>
67#include <openssl/x509.h>
68
69#include "x509_local.h"
70
71X509 *
72X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
73{
74 X509 *ret = NULL;
75 X509_CINF *xi = NULL;
76 X509_NAME *xn;
77 EVP_PKEY *pubkey;
78
79 if ((ret = X509_new()) == NULL) {
80 X509error(ERR_R_MALLOC_FAILURE);
81 goto err;
82 }
83
84 /* duplicate the request */
85 xi = ret->cert_info;
86
87 if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) {
88 if (!X509_set_version(ret, 2))
89 goto err;
90 }
91
92 xn = X509_REQ_get_subject_name(r);
93 if (X509_set_subject_name(ret, xn) == 0)
94 goto err;
95 if (X509_set_issuer_name(ret, xn) == 0)
96 goto err;
97
98 if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
99 goto err;
100 if (X509_gmtime_adj(xi->validity->notAfter,
101 (long)60 * 60 * 24 * days) == NULL)
102 goto err;
103
104 if ((pubkey = X509_REQ_get0_pubkey(r)) == NULL)
105 goto err;
106 if (!X509_set_pubkey(ret, pubkey))
107 goto err;
108
109 if (!X509_sign(ret, pkey, EVP_md5()))
110 goto err;
111 return ret;
112
113err:
114 X509_free(ret);
115 return NULL;
116}
117LCRYPTO_ALIAS(X509_REQ_to_X509);
diff --git a/src/lib/libcrypto/x509/x509_req.c b/src/lib/libcrypto/x509/x509_req.c
deleted file mode 100644
index 704acbd897..0000000000
--- a/src/lib/libcrypto/x509/x509_req.c
+++ /dev/null
@@ -1,320 +0,0 @@
1/* $OpenBSD: x509_req.c,v 1.43 2024/08/31 10:16:52 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/opensslconf.h>
62
63#include <openssl/asn1.h>
64#include <openssl/asn1t.h>
65#include <openssl/bn.h>
66#include <openssl/buffer.h>
67#include <openssl/err.h>
68#include <openssl/evp.h>
69#include <openssl/objects.h>
70#include <openssl/pem.h>
71#include <openssl/x509.h>
72
73#include "asn1_local.h"
74#include "evp_local.h"
75#include "x509_local.h"
76
77X509_REQ *
78X509_to_X509_REQ(X509 *x509, EVP_PKEY *signing_key, const EVP_MD *signing_md)
79{
80 X509_REQ *req;
81 X509_NAME *subject;
82 EVP_PKEY *public_key;
83
84 if ((req = X509_REQ_new()) == NULL) {
85 X509error(ERR_R_MALLOC_FAILURE);
86 goto err;
87 }
88
89 if ((subject = X509_get_subject_name(x509)) == NULL)
90 goto err;
91 if (!X509_REQ_set_subject_name(req, subject))
92 goto err;
93
94 if ((public_key = X509_get0_pubkey(x509)) == NULL)
95 goto err;
96 if (!X509_REQ_set_pubkey(req, public_key))
97 goto err;
98
99 if (signing_key != NULL) {
100 if (!X509_REQ_sign(req, signing_key, signing_md))
101 goto err;
102 }
103
104 return req;
105
106 err:
107 X509_REQ_free(req);
108
109 return NULL;
110}
111LCRYPTO_ALIAS(X509_to_X509_REQ);
112
113EVP_PKEY *
114X509_REQ_get_pubkey(X509_REQ *req)
115{
116 if (req == NULL || req->req_info == NULL)
117 return NULL;
118 return X509_PUBKEY_get(req->req_info->pubkey);
119}
120LCRYPTO_ALIAS(X509_REQ_get_pubkey);
121
122EVP_PKEY *
123X509_REQ_get0_pubkey(X509_REQ *req)
124{
125 if (req == NULL || req->req_info == NULL)
126 return NULL;
127 return X509_PUBKEY_get0(req->req_info->pubkey);
128}
129LCRYPTO_ALIAS(X509_REQ_get0_pubkey);
130
131int
132X509_REQ_check_private_key(X509_REQ *req, EVP_PKEY *pkey)
133{
134 EVP_PKEY *req_pubkey = NULL;
135 int ret;
136
137 if ((req_pubkey = X509_REQ_get0_pubkey(req)) == NULL)
138 return 0;
139
140 if ((ret = EVP_PKEY_cmp(req_pubkey, pkey)) == 1)
141 return 1;
142
143 switch (ret) {
144 case 0:
145 X509error(X509_R_KEY_VALUES_MISMATCH);
146 return 0;
147 case -1:
148 X509error(X509_R_KEY_TYPE_MISMATCH);
149 return 0;
150 case -2:
151#ifndef OPENSSL_NO_EC
152 if (pkey->type == EVP_PKEY_EC) {
153 X509error(ERR_R_EC_LIB);
154 return 0;
155 }
156#endif
157#ifndef OPENSSL_NO_DH
158 if (pkey->type == EVP_PKEY_DH) {
159 /* No idea */
160 X509error(X509_R_CANT_CHECK_DH_KEY);
161 return 0;
162 }
163#endif
164 X509error(X509_R_UNKNOWN_KEY_TYPE);
165 return 0;
166 }
167
168 return 0;
169}
170LCRYPTO_ALIAS(X509_REQ_check_private_key);
171
172int
173X509_REQ_extension_nid(int nid)
174{
175 return nid == NID_ext_req || nid == NID_ms_ext_req;
176}
177LCRYPTO_ALIAS(X509_REQ_extension_nid);
178
179STACK_OF(X509_EXTENSION) *
180X509_REQ_get_extensions(X509_REQ *req)
181{
182 X509_ATTRIBUTE *attr;
183 ASN1_TYPE *ext = NULL;
184 int idx;
185
186 if (req == NULL || req->req_info == NULL)
187 return NULL;
188
189 if ((idx = X509_REQ_get_attr_by_NID(req, NID_ext_req, -1)) == -1)
190 idx = X509_REQ_get_attr_by_NID(req, NID_ms_ext_req, -1);
191 if (idx == -1)
192 return NULL;
193
194 if ((attr = X509_REQ_get_attr(req, idx)) == NULL)
195 return NULL;
196 if ((ext = X509_ATTRIBUTE_get0_type(attr, 0)) == NULL)
197 return NULL;
198
199 return ASN1_TYPE_unpack_sequence(&X509_EXTENSIONS_it, ext);
200}
201LCRYPTO_ALIAS(X509_REQ_get_extensions);
202
203/*
204 * Add a STACK_OF extensions to a certificate request: allow alternative OIDs
205 * in case we want to create a non-standard one.
206 */
207
208int
209X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
210 int nid)
211{
212 unsigned char *ext = NULL;
213 int extlen;
214 int ret;
215
216 if ((extlen = i2d_X509_EXTENSIONS(exts, &ext)) <= 0)
217 return 0;
218
219 ret = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen);
220 free(ext);
221
222 return ret;
223}
224LCRYPTO_ALIAS(X509_REQ_add_extensions_nid);
225
226/* This is the normal usage: use the "official" OID */
227int
228X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
229{
230 return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
231}
232LCRYPTO_ALIAS(X509_REQ_add_extensions);
233
234/* Request attribute functions */
235
236int
237X509_REQ_get_attr_count(const X509_REQ *req)
238{
239 return sk_X509_ATTRIBUTE_num(req->req_info->attributes);
240}
241LCRYPTO_ALIAS(X509_REQ_get_attr_count);
242
243int
244X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
245{
246 return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
247}
248LCRYPTO_ALIAS(X509_REQ_get_attr_by_NID);
249
250int
251X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
252 int lastpos)
253{
254 return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
255}
256LCRYPTO_ALIAS(X509_REQ_get_attr_by_OBJ);
257
258X509_ATTRIBUTE *
259X509_REQ_get_attr(const X509_REQ *req, int loc)
260{
261 return sk_X509_ATTRIBUTE_value(req->req_info->attributes, loc);
262}
263LCRYPTO_ALIAS(X509_REQ_get_attr);
264
265X509_ATTRIBUTE *
266X509_REQ_delete_attr(X509_REQ *req, int loc)
267{
268 return sk_X509_ATTRIBUTE_delete(req->req_info->attributes, loc);
269}
270LCRYPTO_ALIAS(X509_REQ_delete_attr);
271
272int
273X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
274{
275 if (X509at_add1_attr(&req->req_info->attributes, attr))
276 return 1;
277 return 0;
278}
279LCRYPTO_ALIAS(X509_REQ_add1_attr);
280
281int
282X509_REQ_add1_attr_by_OBJ(X509_REQ *req, const ASN1_OBJECT *obj, int type,
283 const unsigned char *bytes, int len)
284{
285 if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
286 type, bytes, len))
287 return 1;
288 return 0;
289}
290LCRYPTO_ALIAS(X509_REQ_add1_attr_by_OBJ);
291
292int
293X509_REQ_add1_attr_by_NID(X509_REQ *req, int nid, int type,
294 const unsigned char *bytes, int len)
295{
296 if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
297 type, bytes, len))
298 return 1;
299 return 0;
300}
301LCRYPTO_ALIAS(X509_REQ_add1_attr_by_NID);
302
303int
304X509_REQ_add1_attr_by_txt(X509_REQ *req, const char *attrname, int type,
305 const unsigned char *bytes, int len)
306{
307 if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
308 type, bytes, len))
309 return 1;
310 return 0;
311}
312LCRYPTO_ALIAS(X509_REQ_add1_attr_by_txt);
313
314int
315i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp)
316{
317 req->req_info->enc.modified = 1;
318 return i2d_X509_REQ_INFO(req->req_info, pp);
319}
320LCRYPTO_ALIAS(i2d_re_X509_REQ_tbs);
diff --git a/src/lib/libcrypto/x509/x509_set.c b/src/lib/libcrypto/x509/x509_set.c
deleted file mode 100644
index 442bc12827..0000000000
--- a/src/lib/libcrypto/x509/x509_set.c
+++ /dev/null
@@ -1,268 +0,0 @@
1/* $OpenBSD: x509_set.c,v 1.29 2024/03/26 23:21:36 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/evp.h>
63#include <openssl/objects.h>
64#include <openssl/x509.h>
65
66#include "x509_local.h"
67
68const STACK_OF(X509_EXTENSION) *
69X509_get0_extensions(const X509 *x)
70{
71 return x->cert_info->extensions;
72}
73LCRYPTO_ALIAS(X509_get0_extensions);
74
75const X509_ALGOR *
76X509_get0_tbs_sigalg(const X509 *x)
77{
78 return x->cert_info->signature;
79}
80LCRYPTO_ALIAS(X509_get0_tbs_sigalg);
81
82int
83X509_set_version(X509 *x, long version)
84{
85 if (x == NULL)
86 return 0;
87 /*
88 * RFC 5280, 4.1: versions 1 - 3 are specified as follows.
89 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
90 */
91 if (version < 0 || version > 2)
92 return 0;
93 if (x->cert_info->version == NULL) {
94 if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL)
95 return 0;
96 }
97 x->cert_info->enc.modified = 1;
98 return ASN1_INTEGER_set(x->cert_info->version, version);
99}
100LCRYPTO_ALIAS(X509_set_version);
101
102long
103X509_get_version(const X509 *x)
104{
105 return ASN1_INTEGER_get(x->cert_info->version);
106}
107LCRYPTO_ALIAS(X509_get_version);
108
109int
110X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
111{
112 ASN1_INTEGER *in;
113
114 if (x == NULL)
115 return 0;
116 in = x->cert_info->serialNumber;
117 if (in != serial) {
118 in = ASN1_INTEGER_dup(serial);
119 if (in != NULL) {
120 x->cert_info->enc.modified = 1;
121 ASN1_INTEGER_free(x->cert_info->serialNumber);
122 x->cert_info->serialNumber = in;
123 }
124 }
125 return in != NULL;
126}
127LCRYPTO_ALIAS(X509_set_serialNumber);
128
129int
130X509_set_issuer_name(X509 *x, X509_NAME *name)
131{
132 if (x == NULL || x->cert_info == NULL)
133 return 0;
134 x->cert_info->enc.modified = 1;
135 return X509_NAME_set(&x->cert_info->issuer, name);
136}
137LCRYPTO_ALIAS(X509_set_issuer_name);
138
139int
140X509_set_subject_name(X509 *x, X509_NAME *name)
141{
142 if (x == NULL || x->cert_info == NULL)
143 return 0;
144 x->cert_info->enc.modified = 1;
145 return X509_NAME_set(&x->cert_info->subject, name);
146}
147LCRYPTO_ALIAS(X509_set_subject_name);
148
149const ASN1_TIME *
150X509_get0_notBefore(const X509 *x)
151{
152 return X509_getm_notBefore(x);
153}
154LCRYPTO_ALIAS(X509_get0_notBefore);
155
156ASN1_TIME *
157X509_getm_notBefore(const X509 *x)
158{
159 if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL)
160 return NULL;
161 return x->cert_info->validity->notBefore;
162}
163LCRYPTO_ALIAS(X509_getm_notBefore);
164
165int
166X509_set_notBefore(X509 *x, const ASN1_TIME *tm)
167{
168 ASN1_TIME *in;
169
170 if (x == NULL || x->cert_info->validity == NULL)
171 return 0;
172 in = x->cert_info->validity->notBefore;
173 if (in != tm) {
174 in = ASN1_STRING_dup(tm);
175 if (in != NULL) {
176 x->cert_info->enc.modified = 1;
177 ASN1_TIME_free(x->cert_info->validity->notBefore);
178 x->cert_info->validity->notBefore = in;
179 }
180 }
181 return in != NULL;
182}
183LCRYPTO_ALIAS(X509_set_notBefore);
184
185int
186X509_set1_notBefore(X509 *x, const ASN1_TIME *tm)
187{
188 return X509_set_notBefore(x, tm);
189}
190LCRYPTO_ALIAS(X509_set1_notBefore);
191
192const ASN1_TIME *
193X509_get0_notAfter(const X509 *x)
194{
195 return X509_getm_notAfter(x);
196}
197LCRYPTO_ALIAS(X509_get0_notAfter);
198
199ASN1_TIME *
200X509_getm_notAfter(const X509 *x)
201{
202 if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL)
203 return NULL;
204 return x->cert_info->validity->notAfter;
205}
206LCRYPTO_ALIAS(X509_getm_notAfter);
207
208int
209X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
210{
211 ASN1_TIME *in;
212
213 if (x == NULL || x->cert_info->validity == NULL)
214 return 0;
215 in = x->cert_info->validity->notAfter;
216 if (in != tm) {
217 in = ASN1_STRING_dup(tm);
218 if (in != NULL) {
219 x->cert_info->enc.modified = 1;
220 ASN1_TIME_free(x->cert_info->validity->notAfter);
221 x->cert_info->validity->notAfter = in;
222 }
223 }
224 return in != NULL;
225}
226LCRYPTO_ALIAS(X509_set_notAfter);
227
228int
229X509_set1_notAfter(X509 *x, const ASN1_TIME *tm)
230{
231 return X509_set_notAfter(x, tm);
232}
233LCRYPTO_ALIAS(X509_set1_notAfter);
234
235int
236X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
237{
238 if (x == NULL || x->cert_info == NULL)
239 return 0;
240 x->cert_info->enc.modified = 1;
241 return X509_PUBKEY_set(&x->cert_info->key, pkey);
242}
243LCRYPTO_ALIAS(X509_set_pubkey);
244
245int
246X509_get_signature_type(const X509 *x)
247{
248 return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg->algorithm));
249}
250LCRYPTO_ALIAS(X509_get_signature_type);
251
252X509_PUBKEY *
253X509_get_X509_PUBKEY(const X509 *x)
254{
255 return x->cert_info->key;
256}
257LCRYPTO_ALIAS(X509_get_X509_PUBKEY);
258
259void
260X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **issuerUID,
261 const ASN1_BIT_STRING **subjectUID)
262{
263 if (issuerUID != NULL)
264 *issuerUID = x->cert_info->issuerUID;
265 if (subjectUID != NULL)
266 *subjectUID = x->cert_info->subjectUID;
267}
268LCRYPTO_ALIAS(X509_get0_uids);
diff --git a/src/lib/libcrypto/x509/x509_siginfo.c b/src/lib/libcrypto/x509/x509_siginfo.c
deleted file mode 100644
index 9bbb133216..0000000000
--- a/src/lib/libcrypto/x509/x509_siginfo.c
+++ /dev/null
@@ -1,113 +0,0 @@
1/* $OpenBSD: x509_siginfo.c,v 1.1 2024/08/28 07:15:04 tb Exp $ */
2
3/*
4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <openssl/evp.h>
20#include <openssl/objects.h>
21#include <openssl/x509.h>
22
23#include "evp_local.h"
24
25#include "x509_internal.h"
26
27static int
28x509_find_sigid_algs(const X509 *x509, int *out_md_nid, int *out_pkey_nid)
29{
30 const ASN1_OBJECT *aobj;
31 int nid;
32
33 *out_md_nid = NID_undef;
34 *out_pkey_nid = NID_undef;
35
36 X509_ALGOR_get0(&aobj, NULL, NULL, x509->sig_alg);
37 if ((nid = OBJ_obj2nid(aobj)) == NID_undef)
38 return 0;
39
40 return OBJ_find_sigid_algs(nid, out_md_nid, out_pkey_nid);
41}
42
43int
44X509_get_signature_info(X509 *x509, int *out_md_nid, int *out_pkey_nid,
45 int *out_security_bits, uint32_t *out_flags)
46{
47 const EVP_MD *md;
48 int md_nid = NID_undef, pkey_nid = NID_undef, security_bits = -1;
49 uint32_t flags = 0;
50
51 if (out_md_nid != NULL)
52 *out_md_nid = md_nid;
53 if (out_pkey_nid != NULL)
54 *out_pkey_nid = pkey_nid;
55 if (out_security_bits != NULL)
56 *out_security_bits = security_bits;
57 if (out_flags != NULL)
58 *out_flags = flags;
59
60 if (!x509v3_cache_extensions(x509))
61 goto err;
62
63 if (!x509_find_sigid_algs(x509, &md_nid, &pkey_nid))
64 goto err;
65
66 /*
67 * If md_nid == NID_undef, this means we need to consult the ameth.
68 * Handlers are available for EdDSA and RSA-PSS. No other signature
69 * algorithm with NID_undef should appear in a certificate.
70 */
71 if (md_nid == NID_undef) {
72 const EVP_PKEY_ASN1_METHOD *ameth;
73
74 if ((ameth = EVP_PKEY_asn1_find(NULL, pkey_nid)) == NULL ||
75 ameth->signature_info == NULL)
76 goto err;
77
78 if (!ameth->signature_info(x509->sig_alg, &md_nid, &pkey_nid,
79 &security_bits, &flags))
80 goto err;
81
82 goto done;
83 }
84
85 /* XXX - OpenSSL 3 special cases SHA-1 (63 bits) and MD5 (39 bits). */
86 if ((md = EVP_get_digestbynid(md_nid)) == NULL)
87 goto err;
88
89 /* Assume 4 bits of collision resistance per octet. */
90 if ((security_bits = EVP_MD_size(md)) <= 0)
91 goto err;
92 security_bits *= 4;
93
94 if (md_nid == NID_sha1 || md_nid == NID_sha256 ||
95 md_nid == NID_sha384 || md_nid == NID_sha512)
96 flags |= X509_SIG_INFO_TLS;
97
98 flags |= X509_SIG_INFO_VALID;
99
100 done:
101 if (out_md_nid != NULL)
102 *out_md_nid = md_nid;
103 if (out_pkey_nid != NULL)
104 *out_pkey_nid = pkey_nid;
105 if (out_security_bits != NULL)
106 *out_security_bits = security_bits;
107 if (out_flags != NULL)
108 *out_flags = flags;
109
110 err:
111 return (flags & X509_SIG_INFO_VALID) != 0;
112}
113LCRYPTO_ALIAS(X509_get_signature_info);
diff --git a/src/lib/libcrypto/x509/x509_skey.c b/src/lib/libcrypto/x509/x509_skey.c
deleted file mode 100644
index d2c90b6f1c..0000000000
--- a/src/lib/libcrypto/x509/x509_skey.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/* $OpenBSD: x509_skey.c,v 1.6 2024/07/13 15:08:58 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/err.h>
63#include <openssl/x509v3.h>
64
65#include "x509_local.h"
66
67static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
68 X509V3_CTX *ctx, char *str);
69
70static const X509V3_EXT_METHOD x509v3_ext_subject_key_identifier = {
71 .ext_nid = NID_subject_key_identifier,
72 .ext_flags = 0,
73 .it = &ASN1_OCTET_STRING_it,
74 .ext_new = NULL,
75 .ext_free = NULL,
76 .d2i = NULL,
77 .i2d = NULL,
78 .i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
79 .s2i = (X509V3_EXT_S2I)s2i_skey_id,
80 .i2v = NULL,
81 .v2i = NULL,
82 .i2r = NULL,
83 .r2i = NULL,
84 .usr_data = NULL,
85};
86
87const X509V3_EXT_METHOD *
88x509v3_ext_method_subject_key_identifier(void)
89{
90 return &x509v3_ext_subject_key_identifier;
91}
92
93char *
94i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, const ASN1_OCTET_STRING *oct)
95{
96 return hex_to_string(oct->data, oct->length);
97}
98LCRYPTO_ALIAS(i2s_ASN1_OCTET_STRING);
99
100ASN1_OCTET_STRING *
101s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
102 const char *str)
103{
104 ASN1_OCTET_STRING *oct;
105 long length;
106
107 if (!(oct = ASN1_OCTET_STRING_new())) {
108 X509V3error(ERR_R_MALLOC_FAILURE);
109 return NULL;
110 }
111
112 if (!(oct->data = string_to_hex(str, &length))) {
113 ASN1_OCTET_STRING_free(oct);
114 return NULL;
115 }
116
117 oct->length = length;
118
119 return oct;
120}
121LCRYPTO_ALIAS(s2i_ASN1_OCTET_STRING);
122
123static ASN1_OCTET_STRING *
124s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str)
125{
126 ASN1_OCTET_STRING *oct;
127 ASN1_BIT_STRING *pk;
128 unsigned char pkey_dig[EVP_MAX_MD_SIZE];
129 unsigned int diglen;
130
131 if (strcmp(str, "hash"))
132 return s2i_ASN1_OCTET_STRING(method, ctx, str);
133
134 if (!(oct = ASN1_OCTET_STRING_new())) {
135 X509V3error(ERR_R_MALLOC_FAILURE);
136 return NULL;
137 }
138
139 if (ctx && (ctx->flags == CTX_TEST))
140 return oct;
141
142 if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
143 X509V3error(X509V3_R_NO_PUBLIC_KEY);
144 goto err;
145 }
146
147 if (ctx->subject_req)
148 pk = ctx->subject_req->req_info->pubkey->public_key;
149 else
150 pk = ctx->subject_cert->cert_info->key->public_key;
151
152 if (!pk) {
153 X509V3error(X509V3_R_NO_PUBLIC_KEY);
154 goto err;
155 }
156
157 if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen,
158 EVP_sha1(), NULL))
159 goto err;
160
161 if (!ASN1_STRING_set(oct, pkey_dig, diglen)) {
162 X509V3error(ERR_R_MALLOC_FAILURE);
163 goto err;
164 }
165
166 return oct;
167
168err:
169 ASN1_OCTET_STRING_free(oct);
170 return NULL;
171}
diff --git a/src/lib/libcrypto/x509/x509_trs.c b/src/lib/libcrypto/x509/x509_trs.c
deleted file mode 100644
index e7e42a83cd..0000000000
--- a/src/lib/libcrypto/x509/x509_trs.c
+++ /dev/null
@@ -1,173 +0,0 @@
1/* $OpenBSD: x509_trs.c,v 1.58 2024/08/31 10:12:23 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/objects.h>
63#include <openssl/x509.h>
64#include <openssl/x509v3.h>
65
66#include "x509_internal.h"
67#include "x509_local.h"
68
69static int
70trust_if_self_signed(const X509 *x)
71{
72 /* Extensions already cached in X509_check_trust(). */
73 if ((x->ex_flags & EXFLAG_SS) != 0)
74 return X509_TRUST_TRUSTED;
75
76 return X509_TRUST_UNTRUSTED;
77}
78
79static int
80trust_was_set(const X509 *x)
81{
82 return x->aux != NULL && (x->aux->trust != NULL ||
83 x->aux->reject != NULL);
84}
85
86static int
87obj_trust(int id, const X509 *x)
88{
89 const X509_CERT_AUX *aux;
90 ASN1_OBJECT *obj;
91 int i, nid;
92
93 if ((aux = x->aux) == NULL)
94 return X509_TRUST_UNTRUSTED;
95
96 for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
97 obj = sk_ASN1_OBJECT_value(aux->reject, i);
98 nid = OBJ_obj2nid(obj);
99 if (nid == id || nid == NID_anyExtendedKeyUsage)
100 return X509_TRUST_REJECTED;
101 }
102
103 for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
104 obj = sk_ASN1_OBJECT_value(aux->trust, i);
105 nid = OBJ_obj2nid(obj);
106 if (nid == id || nid == NID_anyExtendedKeyUsage)
107 return X509_TRUST_TRUSTED;
108 }
109
110 return X509_TRUST_UNTRUSTED;
111}
112
113static int
114nid_from_trust_id(int trust_id)
115{
116 OPENSSL_assert(trust_id == 0 ||
117 (trust_id >= X509_TRUST_MIN && trust_id <= X509_TRUST_MAX));
118
119 switch (trust_id) {
120 case X509_TRUST_COMPAT:
121 return NID_undef;
122 case X509_TRUST_SSL_CLIENT:
123 return NID_client_auth;
124 case X509_TRUST_SSL_SERVER:
125 return NID_server_auth;
126 case X509_TRUST_EMAIL:
127 return NID_email_protect;
128 case X509_TRUST_OBJECT_SIGN:
129 return NID_code_sign;
130 case X509_TRUST_OCSP_SIGN:
131 return NID_OCSP_sign;
132 case X509_TRUST_OCSP_REQUEST:
133 return NID_ad_OCSP;
134 case X509_TRUST_TSA:
135 return NID_time_stamp;
136 default:
137 return NID_undef;
138 }
139}
140
141int
142X509_check_trust(X509 *x, int trust_id, int flags)
143{
144 int rv;
145
146 /* Call early so the trust handlers don't need to modify the certs. */
147 if (!x509v3_cache_extensions(x))
148 return X509_TRUST_UNTRUSTED;
149
150 if (trust_id == X509_TRUST_ACCEPT_ALL)
151 return 1;
152
153 switch (trust_id) {
154 case X509_TRUST_COMPAT:
155 return trust_if_self_signed(x);
156 case X509_TRUST_EMAIL:
157 case X509_TRUST_OBJECT_SIGN:
158 case X509_TRUST_SSL_SERVER:
159 case X509_TRUST_SSL_CLIENT:
160 case X509_TRUST_TSA:
161 if (trust_was_set(x))
162 return obj_trust(nid_from_trust_id(trust_id), x);
163 return trust_if_self_signed(x);
164 case X509_TRUST_OCSP_SIGN:
165 case X509_TRUST_OCSP_REQUEST:
166 return obj_trust(nid_from_trust_id(trust_id), x);
167 default:
168 rv = obj_trust(NID_anyExtendedKeyUsage, x);
169 if (rv != X509_TRUST_UNTRUSTED)
170 return rv;
171 return trust_if_self_signed(x);
172 }
173}
diff --git a/src/lib/libcrypto/x509/x509_txt.c b/src/lib/libcrypto/x509/x509_txt.c
deleted file mode 100644
index 5f5bc5ae84..0000000000
--- a/src/lib/libcrypto/x509/x509_txt.c
+++ /dev/null
@@ -1,196 +0,0 @@
1/* $OpenBSD: x509_txt.c,v 1.28 2023/02/16 08:38:17 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/x509_vfy.h>
60
61const char *
62X509_verify_cert_error_string(long n)
63{
64 switch ((int)n) {
65 case X509_V_OK:
66 return "ok";
67 case X509_V_ERR_UNSPECIFIED:
68 return "Unspecified certificate verification error";
69 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
70 return "unable to get issuer certificate";
71 case X509_V_ERR_UNABLE_TO_GET_CRL:
72 return "unable to get certificate CRL";
73 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
74 return "unable to decrypt certificate's signature";
75 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
76 return "unable to decrypt CRL's signature";
77 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
78 return "unable to decode issuer public key";
79 case X509_V_ERR_CERT_SIGNATURE_FAILURE:
80 return "certificate signature failure";
81 case X509_V_ERR_CRL_SIGNATURE_FAILURE:
82 return "CRL signature failure";
83 case X509_V_ERR_CERT_NOT_YET_VALID:
84 return "certificate is not yet valid";
85 case X509_V_ERR_CERT_HAS_EXPIRED:
86 return "certificate has expired";
87 case X509_V_ERR_CRL_NOT_YET_VALID:
88 return "CRL is not yet valid";
89 case X509_V_ERR_CRL_HAS_EXPIRED:
90 return "CRL has expired";
91 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
92 return "format error in certificate's notBefore field";
93 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
94 return "format error in certificate's notAfter field";
95 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
96 return "format error in CRL's lastUpdate field";
97 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
98 return "format error in CRL's nextUpdate field";
99 case X509_V_ERR_OUT_OF_MEM:
100 return "out of memory";
101 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
102 return "self signed certificate";
103 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
104 return "self signed certificate in certificate chain";
105 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
106 return "unable to get local issuer certificate";
107 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
108 return "unable to verify the first certificate";
109 case X509_V_ERR_CERT_CHAIN_TOO_LONG:
110 return "certificate chain too long";
111 case X509_V_ERR_CERT_REVOKED:
112 return "certificate revoked";
113 case X509_V_ERR_INVALID_CA:
114 return "invalid CA certificate";
115 case X509_V_ERR_PATH_LENGTH_EXCEEDED:
116 return "path length constraint exceeded";
117 case X509_V_ERR_INVALID_PURPOSE:
118 return "unsupported certificate purpose";
119 case X509_V_ERR_CERT_UNTRUSTED:
120 return "certificate not trusted";
121 case X509_V_ERR_CERT_REJECTED:
122 return "certificate rejected";
123 case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
124 return "subject issuer mismatch";
125 case X509_V_ERR_AKID_SKID_MISMATCH:
126 return "authority and subject key identifier mismatch";
127 case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
128 return "authority and issuer serial number mismatch";
129 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
130 return "key usage does not include certificate signing";
131 case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
132 return "unable to get CRL issuer certificate";
133 case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
134 return "unhandled critical extension";
135 case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
136 return "key usage does not include CRL signing";
137 case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
138 return "unhandled critical CRL extension";
139 case X509_V_ERR_INVALID_NON_CA:
140 return "invalid non-CA certificate (has CA markings)";
141 case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
142 return "proxy path length constraint exceeded";
143 case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
144 return "key usage does not include digital signature";
145 case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
146 return "proxy certificates not allowed, "
147 "please set the appropriate flag";
148 case X509_V_ERR_INVALID_EXTENSION:
149 return "invalid or inconsistent certificate extension";
150 case X509_V_ERR_INVALID_POLICY_EXTENSION:
151 return "invalid or inconsistent certificate policy extension";
152 case X509_V_ERR_NO_EXPLICIT_POLICY:
153 return "no explicit policy";
154 case X509_V_ERR_DIFFERENT_CRL_SCOPE:
155 return "Different CRL scope";
156 case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
157 return "Unsupported extension feature";
158 case X509_V_ERR_UNNESTED_RESOURCE:
159 return "RFC 3779 resource not subset of parent's resources";
160 case X509_V_ERR_PERMITTED_VIOLATION:
161 return "permitted subtree violation";
162 case X509_V_ERR_EXCLUDED_VIOLATION:
163 return "excluded subtree violation";
164 case X509_V_ERR_SUBTREE_MINMAX:
165 return "name constraints minimum and maximum not supported";
166 case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
167 return "unsupported name constraint type";
168 case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
169 return "unsupported or invalid name constraint syntax";
170 case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
171 return "unsupported or invalid name syntax";
172 case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
173 return "CRL path validation error";
174 case X509_V_ERR_APPLICATION_VERIFICATION:
175 return "application verification failure";
176 case X509_V_ERR_HOSTNAME_MISMATCH:
177 return "Hostname mismatch";
178 case X509_V_ERR_EMAIL_MISMATCH:
179 return "Email address mismatch";
180 case X509_V_ERR_IP_ADDRESS_MISMATCH:
181 return "IP address mismatch";
182 case X509_V_ERR_INVALID_CALL:
183 return "Invalid certificate verification context";
184 case X509_V_ERR_STORE_LOOKUP:
185 return "Issuer certificate lookup error";
186 case X509_V_ERR_EE_KEY_TOO_SMALL:
187 return "EE certificate key too weak";
188 case X509_V_ERR_CA_KEY_TOO_SMALL:
189 return "CA certificate key too weak";
190 case X509_V_ERR_CA_MD_TOO_WEAK:
191 return "CA signature digest algorithm too weak";
192 default:
193 return "Unknown certificate verification error";
194 }
195}
196LCRYPTO_ALIAS(X509_verify_cert_error_string);
diff --git a/src/lib/libcrypto/x509/x509_utl.c b/src/lib/libcrypto/x509/x509_utl.c
deleted file mode 100644
index 08383849c9..0000000000
--- a/src/lib/libcrypto/x509/x509_utl.c
+++ /dev/null
@@ -1,1494 +0,0 @@
1/* $OpenBSD: x509_utl.c,v 1.26 2025/01/26 13:51:41 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2003 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 */
58
59#include <ctype.h>
60#include <limits.h>
61#include <stdio.h>
62#include <string.h>
63
64#include <openssl/asn1.h>
65#include <openssl/bn.h>
66#include <openssl/conf.h>
67#include <openssl/err.h>
68#include <openssl/x509v3.h>
69
70#include "bytestring.h"
71#include "conf_local.h"
72
73/*
74 * Match reference identifiers starting with "." to any sub-domain. This
75 * flag is set implicitly when the subject reference identity is a DNS name.
76 */
77#define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000
78
79static char *bn_to_string(const BIGNUM *bn);
80static char *strip_spaces(char *name);
81static int sk_strcmp(const char * const *a, const char * const *b);
82static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
83 GENERAL_NAMES *gens);
84static void str_free(OPENSSL_STRING str);
85static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
86
87static int ipv4_from_asc(unsigned char *v4, const char *in);
88static int ipv6_from_asc(unsigned char *v6, const char *in);
89static int ipv6_cb(const char *elem, int len, void *usr);
90static int ipv6_hex(unsigned char *out, const char *in, int inlen);
91
92/* Add a CONF_VALUE name-value pair to stack. */
93int
94X509V3_add_value(const char *name, const char *value,
95 STACK_OF(CONF_VALUE) **out_extlist)
96{
97 STACK_OF(CONF_VALUE) *extlist = NULL;
98 CONF_VALUE *conf_value = NULL;
99 int ret = 0;
100
101 if ((conf_value = calloc(1, sizeof(*conf_value))) == NULL) {
102 X509V3error(ERR_R_MALLOC_FAILURE);
103 goto err;
104 }
105 if (name != NULL) {
106 if ((conf_value->name = strdup(name)) == NULL) {
107 X509V3error(ERR_R_MALLOC_FAILURE);
108 goto err;
109 }
110 }
111 if (value != NULL) {
112 if ((conf_value->value = strdup(value)) == NULL) {
113 X509V3error(ERR_R_MALLOC_FAILURE);
114 goto err;
115 }
116 }
117
118 if ((extlist = *out_extlist) == NULL)
119 extlist = sk_CONF_VALUE_new_null();
120 if (extlist == NULL) {
121 X509V3error(ERR_R_MALLOC_FAILURE);
122 goto err;
123 }
124
125 if (!sk_CONF_VALUE_push(extlist, conf_value)) {
126 X509V3error(ERR_R_MALLOC_FAILURE);
127 goto err;
128 }
129 conf_value = NULL;
130
131 *out_extlist = extlist;
132 extlist = NULL;
133
134 ret = 1;
135
136 err:
137 if (extlist != *out_extlist)
138 sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free);
139 X509V3_conf_free(conf_value);
140
141 return ret;
142}
143
144int
145X509V3_add_value_uchar(const char *name, const unsigned char *value,
146 STACK_OF(CONF_VALUE) **extlist)
147{
148 return X509V3_add_value(name, (const char *)value, extlist);
149}
150
151/* Free function for STACK_OF(CONF_VALUE) */
152
153void
154X509V3_conf_free(CONF_VALUE *conf)
155{
156 if (!conf)
157 return;
158 free(conf->name);
159 free(conf->value);
160 free(conf->section);
161 free(conf);
162}
163LCRYPTO_ALIAS(X509V3_conf_free);
164
165int
166X509V3_add_value_bool(const char *name, int asn1_bool,
167 STACK_OF(CONF_VALUE) **extlist)
168{
169 if (asn1_bool)
170 return X509V3_add_value(name, "TRUE", extlist);
171 return X509V3_add_value(name, "FALSE", extlist);
172}
173
174static char *
175bn_to_string(const BIGNUM *bn)
176{
177 const char *sign = "";
178 char *bnstr, *hex;
179 char *ret = NULL;
180
181 /* Only display small numbers in decimal, as conversion is quadratic. */
182 if (BN_num_bits(bn) < 128)
183 return BN_bn2dec(bn);
184
185 if ((hex = bnstr = BN_bn2hex(bn)) == NULL)
186 goto err;
187
188 if (BN_is_negative(bn)) {
189 sign = "-";
190 hex++;
191 }
192
193 if (asprintf(&ret, "%s0x%s", sign, hex) == -1)
194 ret = NULL;
195
196 err:
197 free(bnstr);
198 return ret;
199}
200
201char *
202i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a)
203{
204 BIGNUM *bntmp;
205 char *strtmp = NULL;
206
207 if (a == NULL)
208 return NULL;
209 if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL ||
210 (strtmp = bn_to_string(bntmp)) == NULL)
211 X509V3error(ERR_R_MALLOC_FAILURE);
212 BN_free(bntmp);
213 return strtmp;
214}
215LCRYPTO_ALIAS(i2s_ASN1_ENUMERATED);
216
217char *
218i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *e)
219{
220 const BIT_STRING_BITNAME *enam;
221 long strval;
222
223 strval = ASN1_ENUMERATED_get(e);
224 for (enam = method->usr_data; enam->lname; enam++) {
225 if (strval == enam->bitnum)
226 return strdup(enam->lname);
227 }
228 return i2s_ASN1_ENUMERATED(method, e);
229}
230LCRYPTO_ALIAS(i2s_ASN1_ENUMERATED_TABLE);
231
232char *
233i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a)
234{
235 BIGNUM *bntmp;
236 char *strtmp = NULL;
237
238 if (a == NULL)
239 return NULL;
240 if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL ||
241 (strtmp = bn_to_string(bntmp)) == NULL)
242 X509V3error(ERR_R_MALLOC_FAILURE);
243 BN_free(bntmp);
244 return strtmp;
245}
246LCRYPTO_ALIAS(i2s_ASN1_INTEGER);
247
248ASN1_INTEGER *
249s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value)
250{
251 BIGNUM *bn = NULL;
252 ASN1_INTEGER *aint;
253 int isneg = 0, ishex = 0;
254 int ret;
255
256 if (!value) {
257 X509V3error(X509V3_R_INVALID_NULL_VALUE);
258 return NULL;
259 }
260 if ((bn = BN_new()) == NULL) {
261 X509V3error(ERR_R_MALLOC_FAILURE);
262 return NULL;
263 }
264 if (value[0] == '-') {
265 value++;
266 isneg = 1;
267 }
268
269 if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) {
270 value += 2;
271 ishex = 1;
272 }
273
274 if (ishex)
275 ret = BN_hex2bn(&bn, value);
276 else
277 ret = BN_dec2bn(&bn, value);
278
279 if (!ret || value[ret]) {
280 BN_free(bn);
281 X509V3error(X509V3_R_BN_DEC2BN_ERROR);
282 return NULL;
283 }
284
285 if (BN_is_zero(bn))
286 isneg = 0;
287
288 aint = BN_to_ASN1_INTEGER(bn, NULL);
289 BN_free(bn);
290 if (!aint) {
291 X509V3error(X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
292 return NULL;
293 }
294 if (isneg)
295 aint->type |= V_ASN1_NEG;
296 return aint;
297}
298LCRYPTO_ALIAS(s2i_ASN1_INTEGER);
299
300int
301X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint,
302 STACK_OF(CONF_VALUE) **extlist)
303{
304 char *strtmp;
305 int ret;
306
307 if (!aint)
308 return 1;
309 if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint)))
310 return 0;
311 ret = X509V3_add_value(name, strtmp, extlist);
312 free(strtmp);
313 return ret;
314}
315
316int
317X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool)
318{
319 char *btmp;
320
321 if (!(btmp = value->value))
322 goto err;
323 if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") ||
324 !strcmp(btmp, "Y") || !strcmp(btmp, "y") ||
325 !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
326 *asn1_bool = 0xff;
327 return 1;
328 } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") ||
329 !strcmp(btmp, "N") || !strcmp(btmp, "n") ||
330 !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
331 *asn1_bool = 0;
332 return 1;
333 }
334
335 err:
336 X509V3error(X509V3_R_INVALID_BOOLEAN_STRING);
337 X509V3_conf_err(value);
338 return 0;
339}
340
341int
342X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint)
343{
344 ASN1_INTEGER *itmp;
345
346 if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
347 X509V3_conf_err(value);
348 return 0;
349 }
350 *aint = itmp;
351 return 1;
352}
353
354#define HDR_NAME 1
355#define HDR_VALUE 2
356
357/*#define DEBUG*/
358
359STACK_OF(CONF_VALUE) *
360X509V3_parse_list(const char *line)
361{
362 char *p, *q, c;
363 char *ntmp, *vtmp;
364 STACK_OF(CONF_VALUE) *values = NULL;
365 char *linebuf;
366 int state;
367
368 /* We are going to modify the line so copy it first */
369 if ((linebuf = strdup(line)) == NULL) {
370 X509V3error(ERR_R_MALLOC_FAILURE);
371 goto err;
372 }
373 state = HDR_NAME;
374 ntmp = NULL;
375
376 /* Go through all characters */
377 for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') &&
378 (c != '\n'); p++) {
379
380 switch (state) {
381 case HDR_NAME:
382 if (c == ':') {
383 state = HDR_VALUE;
384 *p = 0;
385 ntmp = strip_spaces(q);
386 if (!ntmp) {
387 X509V3error(X509V3_R_INVALID_NULL_NAME);
388 goto err;
389 }
390 q = p + 1;
391 } else if (c == ',') {
392 *p = 0;
393 ntmp = strip_spaces(q);
394 q = p + 1;
395 if (!ntmp) {
396 X509V3error(X509V3_R_INVALID_NULL_NAME);
397 goto err;
398 }
399 if (!X509V3_add_value(ntmp, NULL, &values))
400 goto err;
401 }
402 break;
403
404 case HDR_VALUE:
405 if (c == ',') {
406 state = HDR_NAME;
407 *p = 0;
408 vtmp = strip_spaces(q);
409 if (!vtmp) {
410 X509V3error(X509V3_R_INVALID_NULL_VALUE);
411 goto err;
412 }
413 if (!X509V3_add_value(ntmp, vtmp, &values))
414 goto err;
415 ntmp = NULL;
416 q = p + 1;
417 }
418
419 }
420 }
421
422 if (state == HDR_VALUE) {
423 vtmp = strip_spaces(q);
424 if (!vtmp) {
425 X509V3error(X509V3_R_INVALID_NULL_VALUE);
426 goto err;
427 }
428 if (!X509V3_add_value(ntmp, vtmp, &values))
429 goto err;
430 } else {
431 ntmp = strip_spaces(q);
432 if (!ntmp) {
433 X509V3error(X509V3_R_INVALID_NULL_NAME);
434 goto err;
435 }
436 if (!X509V3_add_value(ntmp, NULL, &values))
437 goto err;
438 }
439 free(linebuf);
440 return values;
441
442 err:
443 free(linebuf);
444 sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
445 return NULL;
446}
447LCRYPTO_ALIAS(X509V3_parse_list);
448
449/* Delete leading and trailing spaces from a string */
450static char *
451strip_spaces(char *name)
452{
453 char *p, *q;
454
455 /* Skip over leading spaces */
456 p = name;
457 while (*p && isspace((unsigned char)*p))
458 p++;
459 if (!*p)
460 return NULL;
461 q = p + strlen(p) - 1;
462 while ((q != p) && isspace((unsigned char)*q))
463 q--;
464 if (p != q)
465 q[1] = 0;
466 if (!*p)
467 return NULL;
468 return p;
469}
470
471static const char hex_digits[] = "0123456789ABCDEF";
472
473char *
474hex_to_string(const unsigned char *buffer, long len)
475{
476 CBB cbb;
477 CBS cbs;
478 uint8_t *out = NULL;
479 uint8_t c;
480 size_t out_len;
481
482 if (!CBB_init(&cbb, 0))
483 goto err;
484
485 if (len < 0)
486 goto err;
487
488 CBS_init(&cbs, buffer, len);
489 while (CBS_len(&cbs) > 0) {
490 if (!CBS_get_u8(&cbs, &c))
491 goto err;
492 if (!CBB_add_u8(&cbb, hex_digits[c >> 4]))
493 goto err;
494 if (!CBB_add_u8(&cbb, hex_digits[c & 0xf]))
495 goto err;
496 if (CBS_len(&cbs) > 0) {
497 if (!CBB_add_u8(&cbb, ':'))
498 goto err;
499 }
500 }
501
502 if (!CBB_add_u8(&cbb, '\0'))
503 goto err;
504
505 if (!CBB_finish(&cbb, &out, &out_len))
506 goto err;
507
508 err:
509 CBB_cleanup(&cbb);
510
511 return out;
512}
513LCRYPTO_ALIAS(hex_to_string);
514
515static int
516x509_skip_colons_cbs(CBS *cbs)
517{
518 uint8_t c;
519
520 while (CBS_len(cbs) > 0) {
521 if (!CBS_peek_u8(cbs, &c))
522 return 0;
523 if (c != ':')
524 return 1;
525 if (!CBS_get_u8(cbs, &c))
526 return 0;
527 }
528
529 return 1;
530}
531
532static int
533x509_get_xdigit_nibble_cbs(CBS *cbs, uint8_t *out_nibble)
534{
535 uint8_t c;
536
537 if (!CBS_get_u8(cbs, &c))
538 return 0;
539
540 if (c >= '0' && c <= '9') {
541 *out_nibble = c - '0';
542 return 1;
543 }
544 if (c >= 'a' && c <= 'f') {
545 *out_nibble = c - 'a' + 10;
546 return 1;
547 }
548 if (c >= 'A' && c <= 'F') {
549 *out_nibble = c - 'A' + 10;
550 return 1;
551 }
552
553 X509V3error(X509V3_R_ILLEGAL_HEX_DIGIT);
554 return 0;
555}
556
557unsigned char *
558string_to_hex(const char *str, long *len)
559{
560 CBB cbb;
561 CBS cbs;
562 uint8_t *out = NULL;
563 size_t out_len;
564 uint8_t hi, lo;
565
566 *len = 0;
567
568 if (!CBB_init(&cbb, 0))
569 goto err;
570
571 if (str == NULL) {
572 X509V3error(X509V3_R_INVALID_NULL_ARGUMENT);
573 goto err;
574 }
575
576 CBS_init(&cbs, str, strlen(str));
577 while (CBS_len(&cbs) > 0) {
578 /*
579 * Skipping only a single colon between two pairs of digits
580 * would make more sense - history...
581 */
582 if (!x509_skip_colons_cbs(&cbs))
583 goto err;
584 /* Another historic idiocy. */
585 if (CBS_len(&cbs) == 0)
586 break;
587 if (!x509_get_xdigit_nibble_cbs(&cbs, &hi))
588 goto err;
589 if (CBS_len(&cbs) == 0) {
590 X509V3error(X509V3_R_ODD_NUMBER_OF_DIGITS);
591 goto err;
592 }
593 if (!x509_get_xdigit_nibble_cbs(&cbs, &lo))
594 goto err;
595 if (!CBB_add_u8(&cbb, hi << 4 | lo))
596 goto err;
597 }
598
599 if (!CBB_finish(&cbb, &out, &out_len))
600 goto err;
601 if (out_len > LONG_MAX) {
602 freezero(out, out_len);
603 out = NULL;
604 goto err;
605 }
606
607 *len = out_len;
608
609 err:
610 CBB_cleanup(&cbb);
611
612 return out;
613}
614LCRYPTO_ALIAS(string_to_hex);
615
616/* V2I name comparison function: returns zero if 'name' matches
617 * cmp or cmp.*
618 */
619
620int
621name_cmp(const char *name, const char *cmp)
622{
623 int len, ret;
624 char c;
625
626 len = strlen(cmp);
627 if ((ret = strncmp(name, cmp, len)))
628 return ret;
629 c = name[len];
630 if (!c || (c=='.'))
631 return 0;
632 return 1;
633}
634
635static int
636sk_strcmp(const char * const *a, const char * const *b)
637{
638 return strcmp(*a, *b);
639}
640
641STACK_OF(OPENSSL_STRING) *
642X509_get1_email(X509 *x)
643{
644 GENERAL_NAMES *gens;
645 STACK_OF(OPENSSL_STRING) *ret;
646
647 gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
648 ret = get_email(X509_get_subject_name(x), gens);
649 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
650 return ret;
651}
652LCRYPTO_ALIAS(X509_get1_email);
653
654STACK_OF(OPENSSL_STRING) *
655X509_get1_ocsp(X509 *x)
656{
657 AUTHORITY_INFO_ACCESS *info;
658 STACK_OF(OPENSSL_STRING) *ret = NULL;
659 int i;
660
661 info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
662 if (!info)
663 return NULL;
664 for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
665 ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
666 if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
667 if (ad->location->type == GEN_URI) {
668 if (!append_ia5(&ret,
669 ad->location->d.uniformResourceIdentifier))
670 break;
671 }
672 }
673 }
674 AUTHORITY_INFO_ACCESS_free(info);
675 return ret;
676}
677LCRYPTO_ALIAS(X509_get1_ocsp);
678
679STACK_OF(OPENSSL_STRING) *
680X509_REQ_get1_email(X509_REQ *x)
681{
682 GENERAL_NAMES *gens;
683 STACK_OF(X509_EXTENSION) *exts;
684 STACK_OF(OPENSSL_STRING) *ret;
685
686 exts = X509_REQ_get_extensions(x);
687 gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
688 ret = get_email(X509_REQ_get_subject_name(x), gens);
689 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
690 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
691 return ret;
692}
693LCRYPTO_ALIAS(X509_REQ_get1_email);
694
695
696static STACK_OF(OPENSSL_STRING) *
697get_email(X509_NAME *name, GENERAL_NAMES *gens)
698{
699 STACK_OF(OPENSSL_STRING) *ret = NULL;
700 X509_NAME_ENTRY *ne;
701 ASN1_IA5STRING *email;
702 GENERAL_NAME *gen;
703 int i;
704
705 /* Now add any email address(es) to STACK */
706 i = -1;
707
708 /* First supplied X509_NAME */
709 while ((i = X509_NAME_get_index_by_NID(name,
710 NID_pkcs9_emailAddress, i)) >= 0) {
711 ne = X509_NAME_get_entry(name, i);
712 email = X509_NAME_ENTRY_get_data(ne);
713 if (!append_ia5(&ret, email))
714 return NULL;
715 }
716 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
717 gen = sk_GENERAL_NAME_value(gens, i);
718 if (gen->type != GEN_EMAIL)
719 continue;
720 if (!append_ia5(&ret, gen->d.ia5))
721 return NULL;
722 }
723 return ret;
724}
725
726static void
727str_free(OPENSSL_STRING str)
728{
729 free(str);
730}
731
732static int
733append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
734{
735 char *emtmp;
736
737 /* First some sanity checks */
738 if (email->type != V_ASN1_IA5STRING)
739 return 1;
740 if (!email->data || !email->length)
741 return 1;
742 if (!*sk)
743 *sk = sk_OPENSSL_STRING_new(sk_strcmp);
744 if (!*sk)
745 return 0;
746 /* Don't add duplicates */
747 if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1)
748 return 1;
749 emtmp = strdup((char *)email->data);
750 if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
751 X509_email_free(*sk);
752 *sk = NULL;
753 return 0;
754 }
755 return 1;
756}
757
758void
759X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
760{
761 sk_OPENSSL_STRING_pop_free(sk, str_free);
762}
763LCRYPTO_ALIAS(X509_email_free);
764
765typedef int (*equal_fn)(const unsigned char *pattern, size_t pattern_len,
766 const unsigned char *subject, size_t subject_len, unsigned int flags);
767
768/* Skip pattern prefix to match "wildcard" subject */
769static void
770skip_prefix(const unsigned char **p, size_t *plen, const unsigned char *subject,
771 size_t subject_len, unsigned int flags)
772{
773 const unsigned char *pattern = *p;
774 size_t pattern_len = *plen;
775
776 /*
777 * If subject starts with a leading '.' followed by more octets, and
778 * pattern is longer, compare just an equal-length suffix with the
779 * full subject (starting at the '.'), provided the prefix contains
780 * no NULs.
781 */
782 if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
783 return;
784
785 while (pattern_len > subject_len && *pattern) {
786 if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
787 *pattern == '.')
788 break;
789 ++pattern;
790 --pattern_len;
791 }
792
793 /* Skip if entire prefix acceptable */
794 if (pattern_len == subject_len) {
795 *p = pattern;
796 *plen = pattern_len;
797 }
798}
799
800/*
801 * Open/BoringSSL uses memcmp for "equal_case" while their
802 * "equal_nocase" function is a hand-rolled strncasecmp that does not
803 * allow \0 in the pattern. Since an embedded \0 is likely a sign of
804 * problems, we simply don't allow it in either case, and then we use
805 * standard libc functions.
806 */
807
808/* Compare using strncasecmp */
809static int
810equal_nocase(const unsigned char *pattern, size_t pattern_len,
811 const unsigned char *subject, size_t subject_len, unsigned int flags)
812{
813 if (memchr(pattern, '\0', pattern_len) != NULL)
814 return 0;
815 if (memchr(subject, '\0', subject_len) != NULL)
816 return 0;
817 skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
818 if (pattern_len != subject_len)
819 return 0;
820 return (strncasecmp(pattern, subject, pattern_len) == 0);
821}
822
823/* Compare using strncmp. */
824static int
825equal_case(const unsigned char *pattern, size_t pattern_len,
826 const unsigned char *subject, size_t subject_len, unsigned int flags)
827{
828 if (memchr(pattern, 0, pattern_len) != NULL)
829 return 0;
830 if (memchr(subject, 0, subject_len) != NULL)
831 return 0;
832 skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
833 if (pattern_len != subject_len)
834 return 0;
835 return (strncmp(pattern, subject, pattern_len) == 0);
836}
837
838/*
839 * RFC 5280, section 7.5, requires that only the domain is compared in a
840 * case-insensitive manner.
841 */
842static int
843equal_email(const unsigned char *a, size_t a_len, const unsigned char *b,
844 size_t b_len, unsigned int unused_flags)
845{
846 size_t pos = a_len;
847 if (a_len != b_len)
848 return 0;
849 /*
850 * We search backwards for the '@' character, so that we do not have to
851 * deal with quoted local-parts. The domain part is compared in a
852 * case-insensitive manner.
853 */
854 while (pos > 0) {
855 pos--;
856 if (a[pos] == '@' || b[pos] == '@') {
857 if (!equal_nocase(a + pos, a_len - pos, b + pos,
858 a_len - pos, 0))
859 return 0;
860 break;
861 }
862 }
863 if (pos == 0)
864 pos = a_len;
865 return equal_case(a, pos, b, pos, 0);
866}
867
868/*
869 * Compare the prefix and suffix with the subject, and check that the
870 * characters in-between are valid.
871 */
872static int
873wildcard_match(const unsigned char *prefix, size_t prefix_len,
874 const unsigned char *suffix, size_t suffix_len,
875 const unsigned char *subject, size_t subject_len, unsigned int flags)
876{
877 const unsigned char *wildcard_start;
878 const unsigned char *wildcard_end;
879 const unsigned char *p;
880 int allow_multi = 0;
881 int allow_idna = 0;
882
883 if (subject_len < prefix_len + suffix_len)
884 return 0;
885 if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
886 return 0;
887 wildcard_start = subject + prefix_len;
888 wildcard_end = subject + (subject_len - suffix_len);
889 if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
890 return 0;
891 /*
892 * If the wildcard makes up the entire first label, it must match at
893 * least one character.
894 */
895 if (prefix_len == 0 && *suffix == '.') {
896 if (wildcard_start == wildcard_end)
897 return 0;
898 allow_idna = 1;
899 if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
900 allow_multi = 1;
901 }
902 /* IDNA labels cannot match partial wildcards */
903 if (!allow_idna &&
904 subject_len >= 4
905 && strncasecmp((char *)subject, "xn--", 4) == 0)
906 return 0;
907 /* The wildcard may match a literal '*' */
908 if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
909 return 1;
910 /*
911 * Check that the part matched by the wildcard contains only
912 * permitted characters and only matches a single label unless
913 * allow_multi is set.
914 */
915 for (p = wildcard_start; p != wildcard_end; ++p)
916 if (!(('0' <= *p && *p <= '9') || ('A' <= *p && *p <= 'Z') ||
917 ('a' <= *p && *p <= 'z') || *p == '-' ||
918 (allow_multi && *p == '.')))
919 return 0;
920 return 1;
921}
922
923#define LABEL_START (1 << 0)
924#define LABEL_END (1 << 1)
925#define LABEL_HYPHEN (1 << 2)
926#define LABEL_IDNA (1 << 3)
927
928static const unsigned char *
929valid_star(const unsigned char *p, size_t len, unsigned int flags)
930{
931 const unsigned char *star = 0;
932 size_t i;
933 int state = LABEL_START;
934 int dots = 0;
935 for (i = 0; i < len; ++i) {
936 /*
937 * Locate first and only legal wildcard, either at the start
938 * or end of a non-IDNA first and not final label.
939 */
940 if (p[i] == '*') {
941 int atstart = (state & LABEL_START);
942 int atend = (i == len - 1 || p[i + 1] == '.');
943 /*
944 * At most one wildcard per pattern.
945 * No wildcards in IDNA labels.
946 * No wildcards after the first label.
947 */
948 if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
949 return NULL;
950 /* Only full-label '*.example.com' wildcards? */
951 if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
952 && (!atstart || !atend))
953 return NULL;
954 /* No 'foo*bar' wildcards */
955 if (!atstart && !atend)
956 return NULL;
957 star = &p[i];
958 state &= ~LABEL_START;
959 } else if ((state & LABEL_START) != 0) {
960 /*
961 * At the start of a label, skip any "xn--" and
962 * remain in the LABEL_START state, but set the
963 * IDNA label state
964 */
965 if ((state & LABEL_IDNA) == 0 && len - i >= 4
966 && strncasecmp((char *)&p[i], "xn--", 4) == 0) {
967 i += 3;
968 state |= LABEL_IDNA;
969 continue;
970 }
971 /* Labels must start with a letter or digit */
972 state &= ~LABEL_START;
973 if (('a' <= p[i] && p[i] <= 'z')
974 || ('A' <= p[i] && p[i] <= 'Z')
975 || ('0' <= p[i] && p[i] <= '9'))
976 continue;
977 return NULL;
978 } else if (('a' <= p[i] && p[i] <= 'z')
979 || ('A' <= p[i] && p[i] <= 'Z')
980 || ('0' <= p[i] && p[i] <= '9')) {
981 state &= LABEL_IDNA;
982 continue;
983 } else if (p[i] == '.') {
984 if (state & (LABEL_HYPHEN | LABEL_START))
985 return NULL;
986 state = LABEL_START;
987 ++dots;
988 } else if (p[i] == '-') {
989 /* no domain/subdomain starts with '-' */
990 if ((state & LABEL_START) != 0)
991 return NULL;
992 state |= LABEL_HYPHEN;
993 } else
994 return NULL;
995 }
996
997 /*
998 * The final label must not end in a hyphen or ".", and
999 * there must be at least two dots after the star.
1000 */
1001 if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
1002 return NULL;
1003 return star;
1004}
1005
1006/* Compare using wildcards. */
1007static int
1008equal_wildcard(const unsigned char *pattern, size_t pattern_len,
1009 const unsigned char *subject, size_t subject_len, unsigned int flags)
1010{
1011 const unsigned char *star = NULL;
1012
1013 /*
1014 * Subject names starting with '.' can only match a wildcard pattern
1015 * via a subject sub-domain pattern suffix match.
1016 */
1017 if (!(subject_len > 1 && subject[0] == '.'))
1018 star = valid_star(pattern, pattern_len, flags);
1019 if (star == NULL)
1020 return equal_nocase(pattern, pattern_len,
1021 subject, subject_len, flags);
1022 return wildcard_match(pattern, star - pattern,
1023 star + 1, (pattern + pattern_len) - star - 1,
1024 subject, subject_len, flags);
1025}
1026
1027/*
1028 * Compare an ASN1_STRING to a supplied string. If they match return 1. If
1029 * cmp_type > 0 only compare if string matches the type, otherwise convert it
1030 * to UTF8.
1031 */
1032
1033static int
1034do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal,
1035 unsigned int flags, const char *b, size_t blen, char **peername)
1036{
1037 int rv = 0;
1038
1039 if (!a->data || !a->length)
1040 return 0;
1041 if (cmp_type > 0) {
1042 if (cmp_type != a->type)
1043 return 0;
1044 if (cmp_type == V_ASN1_IA5STRING)
1045 rv = equal(a->data, a->length, (unsigned char *)b,
1046 blen, flags);
1047 else if (a->length == (int)blen && !memcmp(a->data, b, blen))
1048 rv = 1;
1049 if (rv > 0 && peername &&
1050 (*peername = strndup((char *)a->data, a->length)) == NULL)
1051 rv = -1;
1052 } else {
1053 int astrlen;
1054 unsigned char *astr = NULL;
1055 astrlen = ASN1_STRING_to_UTF8(&astr, a);
1056 if (astrlen < 0)
1057 return -1;
1058 rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
1059 if (rv > 0 && peername &&
1060 (*peername = strndup((char *)astr, astrlen)) == NULL)
1061 rv = -1;
1062 free(astr);
1063 }
1064 return rv;
1065}
1066
1067static int
1068do_x509_check(X509 *x, const char *chk, size_t chklen, unsigned int flags,
1069 int check_type, char **peername)
1070{
1071 GENERAL_NAMES *gens = NULL;
1072 X509_NAME *name = NULL;
1073 size_t i;
1074 int j;
1075 int cnid = NID_undef;
1076 int alt_type;
1077 int san_present = 0;
1078 int rv = 0;
1079 equal_fn equal;
1080
1081 /* See below, this flag is internal-only */
1082 flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
1083 if (check_type == GEN_EMAIL) {
1084 cnid = NID_pkcs9_emailAddress;
1085 alt_type = V_ASN1_IA5STRING;
1086 equal = equal_email;
1087 } else if (check_type == GEN_DNS) {
1088 if (!(flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT))
1089 cnid = NID_commonName;
1090 /* Implicit client-side DNS sub-domain pattern */
1091 if (chklen > 1 && chk[0] == '.')
1092 flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
1093 alt_type = V_ASN1_IA5STRING;
1094 if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
1095 equal = equal_nocase;
1096 else
1097 equal = equal_wildcard;
1098 } else {
1099 alt_type = V_ASN1_OCTET_STRING;
1100 equal = equal_case;
1101 }
1102
1103 gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1104 if (gens != NULL) {
1105 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1106 GENERAL_NAME *gen;
1107 ASN1_STRING *cstr;
1108 gen = sk_GENERAL_NAME_value(gens, i);
1109 if (gen->type != check_type)
1110 continue;
1111 san_present = 1;
1112 if (check_type == GEN_EMAIL)
1113 cstr = gen->d.rfc822Name;
1114 else if (check_type == GEN_DNS)
1115 cstr = gen->d.dNSName;
1116 else
1117 cstr = gen->d.iPAddress;
1118 /* Positive on success, negative on error! */
1119 if ((rv = do_check_string(cstr, alt_type, equal, flags,
1120 chk, chklen, peername)) != 0)
1121 break;
1122 }
1123 GENERAL_NAMES_free(gens);
1124 if (rv != 0)
1125 return rv;
1126 if (cnid == NID_undef ||
1127 (san_present &&
1128 !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)))
1129 return 0;
1130 }
1131
1132 /* We're done if CN-ID is not pertinent */
1133 if (cnid == NID_undef)
1134 return 0;
1135
1136 j = -1;
1137 name = X509_get_subject_name(x);
1138 while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) {
1139 X509_NAME_ENTRY *ne;
1140 ASN1_STRING *str;
1141 if ((ne = X509_NAME_get_entry(name, j)) == NULL)
1142 return -1;
1143 if ((str = X509_NAME_ENTRY_get_data(ne)) == NULL)
1144 return -1;
1145 /* Positive on success, negative on error! */
1146 if ((rv = do_check_string(str, -1, equal, flags,
1147 chk, chklen, peername)) != 0)
1148 return rv;
1149 }
1150 return 0;
1151}
1152
1153int
1154X509_check_host(X509 *x, const char *chk, size_t chklen, unsigned int flags,
1155 char **peername)
1156{
1157 if (chk == NULL)
1158 return -2;
1159 if (chklen == 0)
1160 chklen = strlen(chk);
1161 else if (memchr(chk, '\0', chklen))
1162 return -2;
1163 return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
1164}
1165LCRYPTO_ALIAS(X509_check_host);
1166
1167int
1168X509_check_email(X509 *x, const char *chk, size_t chklen, unsigned int flags)
1169{
1170 if (chk == NULL)
1171 return -2;
1172 if (chklen == 0)
1173 chklen = strlen(chk);
1174 else if (memchr(chk, '\0', chklen))
1175 return -2;
1176 return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
1177}
1178LCRYPTO_ALIAS(X509_check_email);
1179
1180int
1181X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
1182 unsigned int flags)
1183{
1184 if (chk == NULL)
1185 return -2;
1186 return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
1187}
1188LCRYPTO_ALIAS(X509_check_ip);
1189
1190int
1191X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
1192{
1193 unsigned char ipout[16];
1194 size_t iplen;
1195
1196 if (ipasc == NULL)
1197 return -2;
1198 iplen = (size_t)a2i_ipadd(ipout, ipasc);
1199 if (iplen == 0)
1200 return -2;
1201 return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
1202}
1203LCRYPTO_ALIAS(X509_check_ip_asc);
1204
1205/* Convert IP addresses both IPv4 and IPv6 into an
1206 * OCTET STRING compatible with RFC3280.
1207 */
1208
1209ASN1_OCTET_STRING *
1210a2i_IPADDRESS(const char *ipasc)
1211{
1212 unsigned char ipout[16];
1213 ASN1_OCTET_STRING *ret;
1214 int iplen;
1215
1216 /* If string contains a ':' assume IPv6 */
1217
1218 iplen = a2i_ipadd(ipout, ipasc);
1219
1220 if (!iplen)
1221 return NULL;
1222
1223 ret = ASN1_OCTET_STRING_new();
1224 if (!ret)
1225 return NULL;
1226 if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
1227 ASN1_OCTET_STRING_free(ret);
1228 return NULL;
1229 }
1230 return ret;
1231}
1232LCRYPTO_ALIAS(a2i_IPADDRESS);
1233
1234ASN1_OCTET_STRING *
1235a2i_IPADDRESS_NC(const char *ipasc)
1236{
1237 ASN1_OCTET_STRING *ret = NULL;
1238 unsigned char ipout[32];
1239 char *iptmp = NULL, *p;
1240 int iplen1, iplen2;
1241
1242 p = strchr(ipasc, '/');
1243 if (!p)
1244 return NULL;
1245 iptmp = strdup(ipasc);
1246 if (!iptmp)
1247 return NULL;
1248 p = iptmp + (p - ipasc);
1249 *p++ = 0;
1250
1251 iplen1 = a2i_ipadd(ipout, iptmp);
1252
1253 if (!iplen1)
1254 goto err;
1255
1256 iplen2 = a2i_ipadd(ipout + iplen1, p);
1257
1258 free(iptmp);
1259 iptmp = NULL;
1260
1261 if (!iplen2 || (iplen1 != iplen2))
1262 goto err;
1263
1264 ret = ASN1_OCTET_STRING_new();
1265 if (!ret)
1266 goto err;
1267 if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
1268 goto err;
1269
1270 return ret;
1271
1272 err:
1273 free(iptmp);
1274 if (ret)
1275 ASN1_OCTET_STRING_free(ret);
1276 return NULL;
1277}
1278LCRYPTO_ALIAS(a2i_IPADDRESS_NC);
1279
1280
1281int
1282a2i_ipadd(unsigned char *ipout, const char *ipasc)
1283{
1284 /* If string contains a ':' assume IPv6 */
1285
1286 if (strchr(ipasc, ':')) {
1287 if (!ipv6_from_asc(ipout, ipasc))
1288 return 0;
1289 return 16;
1290 } else {
1291 if (!ipv4_from_asc(ipout, ipasc))
1292 return 0;
1293 return 4;
1294 }
1295}
1296LCRYPTO_ALIAS(a2i_ipadd);
1297
1298static int
1299ipv4_from_asc(unsigned char *v4, const char *in)
1300{
1301 int a0, a1, a2, a3;
1302 if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
1303 return 0;
1304 if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) ||
1305 (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
1306 return 0;
1307 v4[0] = a0;
1308 v4[1] = a1;
1309 v4[2] = a2;
1310 v4[3] = a3;
1311 return 1;
1312}
1313
1314typedef struct {
1315 /* Temporary store for IPV6 output */
1316 unsigned char tmp[16];
1317 /* Total number of bytes in tmp */
1318 int total;
1319 /* The position of a zero (corresponding to '::') */
1320 int zero_pos;
1321 /* Number of zeroes */
1322 int zero_cnt;
1323} IPV6_STAT;
1324
1325
1326static int
1327ipv6_from_asc(unsigned char *v6, const char *in)
1328{
1329 IPV6_STAT v6stat;
1330
1331 v6stat.total = 0;
1332 v6stat.zero_pos = -1;
1333 v6stat.zero_cnt = 0;
1334
1335 /*
1336 * Treat the IPv6 representation as a list of values separated by ':'.
1337 * The presence of a '::' will parse as one (e.g., "2001:db8::1"),
1338 * two (e.g., "2001:db8::") or three (e.g., "::") zero length elements.
1339 */
1340 if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
1341 return 0;
1342
1343 /* Now for some sanity checks */
1344
1345 if (v6stat.zero_pos == -1) {
1346 /* If no '::' must have exactly 16 bytes */
1347 if (v6stat.total != 16)
1348 return 0;
1349 } else {
1350 /* If '::' must have less than 16 bytes */
1351 if (v6stat.total == 16)
1352 return 0;
1353 /* More than three zeroes is an error */
1354 if (v6stat.zero_cnt > 3)
1355 return 0;
1356 /* Can only have three zeroes if nothing else present */
1357 else if (v6stat.zero_cnt == 3) {
1358 if (v6stat.total > 0)
1359 return 0;
1360 }
1361 /* Can only have two zeroes if at start or end */
1362 else if (v6stat.zero_cnt == 2) {
1363 if ((v6stat.zero_pos != 0) &&
1364 (v6stat.zero_pos != v6stat.total))
1365 return 0;
1366 } else
1367 /* Can only have one zero if *not* start or end */
1368 {
1369 if ((v6stat.zero_pos == 0) ||
1370 (v6stat.zero_pos == v6stat.total))
1371 return 0;
1372 }
1373 }
1374
1375 /* Format result */
1376
1377 if (v6stat.zero_pos >= 0) {
1378 /* Copy initial part */
1379 memcpy(v6, v6stat.tmp, v6stat.zero_pos);
1380 /* Zero middle */
1381 memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
1382 /* Copy final part */
1383 if (v6stat.total != v6stat.zero_pos)
1384 memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
1385 v6stat.tmp + v6stat.zero_pos,
1386 v6stat.total - v6stat.zero_pos);
1387 } else
1388 memcpy(v6, v6stat.tmp, 16);
1389
1390 return 1;
1391}
1392
1393static int
1394ipv6_cb(const char *elem, int len, void *usr)
1395{
1396 IPV6_STAT *s = usr;
1397
1398 /* Error if 16 bytes written */
1399 if (s->total == 16)
1400 return 0;
1401 if (len == 0) {
1402 /* Zero length element, corresponds to '::' */
1403 if (s->zero_pos == -1)
1404 s->zero_pos = s->total;
1405 /* If we've already got a :: its an error */
1406 else if (s->zero_pos != s->total)
1407 return 0;
1408 s->zero_cnt++;
1409 } else {
1410 /* If more than 4 characters could be final a.b.c.d form */
1411 if (len > 4) {
1412 /* Need at least 4 bytes left */
1413 if (s->total > 12)
1414 return 0;
1415 /* Must be end of string */
1416 if (elem[len])
1417 return 0;
1418 if (!ipv4_from_asc(s->tmp + s->total, elem))
1419 return 0;
1420 s->total += 4;
1421 } else {
1422 if (!ipv6_hex(s->tmp + s->total, elem, len))
1423 return 0;
1424 s->total += 2;
1425 }
1426 }
1427 return 1;
1428}
1429
1430/* Convert a string of up to 4 hex digits into the corresponding
1431 * IPv6 form.
1432 */
1433
1434static int
1435ipv6_hex(unsigned char *out, const char *in, int inlen)
1436{
1437 unsigned char c;
1438 unsigned int num = 0;
1439
1440 if (inlen > 4)
1441 return 0;
1442 while (inlen--) {
1443 c = *in++;
1444 num <<= 4;
1445 if ((c >= '0') && (c <= '9'))
1446 num |= c - '0';
1447 else if ((c >= 'A') && (c <= 'F'))
1448 num |= c - 'A' + 10;
1449 else if ((c >= 'a') && (c <= 'f'))
1450 num |= c - 'a' + 10;
1451 else
1452 return 0;
1453 }
1454 out[0] = num >> 8;
1455 out[1] = num & 0xff;
1456 return 1;
1457}
1458
1459int
1460X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
1461 unsigned long chtype)
1462{
1463 CONF_VALUE *v;
1464 int i, mval;
1465 char *p, *type;
1466
1467 if (!nm)
1468 return 0;
1469
1470 for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1471 v = sk_CONF_VALUE_value(dn_sk, i);
1472 type = v->name;
1473 /* Skip past any leading X. X: X, etc to allow for
1474 * multiple instances
1475 */
1476 for (p = type; *p; p++)
1477 if ((*p == ':') || (*p == ',') || (*p == '.')) {
1478 p++;
1479 if (*p)
1480 type = p;
1481 break;
1482 }
1483 if (*type == '+') {
1484 mval = -1;
1485 type++;
1486 } else
1487 mval = 0;
1488 if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
1489 (unsigned char *) v->value, -1, -1, mval))
1490 return 0;
1491 }
1492 return 1;
1493}
1494LCRYPTO_ALIAS(X509V3_NAME_from_section);
diff --git a/src/lib/libcrypto/x509/x509_v3.c b/src/lib/libcrypto/x509/x509_v3.c
deleted file mode 100644
index 688aed15a2..0000000000
--- a/src/lib/libcrypto/x509/x509_v3.c
+++ /dev/null
@@ -1,295 +0,0 @@
1/* $OpenBSD: x509_v3.c,v 1.43 2024/07/12 09:57:04 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/err.h>
63#include <openssl/objects.h>
64#include <openssl/stack.h>
65#include <openssl/x509.h>
66#include <openssl/x509v3.h>
67
68#include "x509_local.h"
69
70int
71X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *exts)
72{
73 if (exts == NULL)
74 return 0;
75
76 return sk_X509_EXTENSION_num(exts);
77}
78LCRYPTO_ALIAS(X509v3_get_ext_count);
79
80int
81X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *exts, int nid, int lastpos)
82{
83 const ASN1_OBJECT *obj;
84
85 if ((obj = OBJ_nid2obj(nid)) == NULL)
86 return -2;
87
88 return X509v3_get_ext_by_OBJ(exts, obj, lastpos);
89}
90LCRYPTO_ALIAS(X509v3_get_ext_by_NID);
91
92int
93X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *exts,
94 const ASN1_OBJECT *obj, int lastpos)
95{
96 if (++lastpos < 0)
97 lastpos = 0;
98
99 for (; lastpos < X509v3_get_ext_count(exts); lastpos++) {
100 const X509_EXTENSION *ext = X509v3_get_ext(exts, lastpos);
101
102 if (OBJ_cmp(ext->object, obj) == 0)
103 return lastpos;
104 }
105
106 return -1;
107}
108LCRYPTO_ALIAS(X509v3_get_ext_by_OBJ);
109
110int
111X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *exts, int critical,
112 int lastpos)
113{
114 critical = (critical != 0);
115
116 if (++lastpos < 0)
117 lastpos = 0;
118
119 for (; lastpos < X509v3_get_ext_count(exts); lastpos++) {
120 const X509_EXTENSION *ext = X509v3_get_ext(exts, lastpos);
121
122 if (X509_EXTENSION_get_critical(ext) == critical)
123 return lastpos;
124 }
125
126 return -1;
127}
128LCRYPTO_ALIAS(X509v3_get_ext_by_critical);
129
130X509_EXTENSION *
131X509v3_get_ext(const STACK_OF(X509_EXTENSION) *exts, int loc)
132{
133 return sk_X509_EXTENSION_value(exts, loc);
134}
135LCRYPTO_ALIAS(X509v3_get_ext);
136
137X509_EXTENSION *
138X509v3_delete_ext(STACK_OF(X509_EXTENSION) *exts, int loc)
139{
140 return sk_X509_EXTENSION_delete(exts, loc);
141}
142LCRYPTO_ALIAS(X509v3_delete_ext);
143
144STACK_OF(X509_EXTENSION) *
145X509v3_add_ext(STACK_OF(X509_EXTENSION) **out_exts, X509_EXTENSION *ext, int loc)
146{
147 STACK_OF(X509_EXTENSION) *exts = NULL;
148 X509_EXTENSION *new_ext = NULL;
149
150 /*
151 * XXX - Nonsense from the poorly reviewed OpenSSL c755c5fd8ba (2005).
152 * This check should have been joined with the next check, i.e., if no
153 * stack was passed in, a new one should be created and returned.
154 */
155 if (out_exts == NULL) {
156 X509error(ERR_R_PASSED_NULL_PARAMETER);
157 goto err;
158 }
159
160 if ((exts = *out_exts) == NULL)
161 exts = sk_X509_EXTENSION_new_null();
162 if (exts == NULL) {
163 X509error(ERR_R_MALLOC_FAILURE);
164 goto err;
165 }
166
167 if ((new_ext = X509_EXTENSION_dup(ext)) == NULL)
168 goto err;
169 if (!sk_X509_EXTENSION_insert(exts, new_ext, loc))
170 goto err;
171 new_ext = NULL;
172
173 *out_exts = exts;
174
175 return exts;
176
177 err:
178 X509_EXTENSION_free(new_ext);
179 if (out_exts != NULL && exts != *out_exts)
180 sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
181
182 return NULL;
183}
184LCRYPTO_ALIAS(X509v3_add_ext);
185
186X509_EXTENSION *
187X509_EXTENSION_create_by_NID(X509_EXTENSION **out_ext, int nid, int critical,
188 ASN1_OCTET_STRING *data)
189{
190 const ASN1_OBJECT *obj;
191
192 if ((obj = OBJ_nid2obj(nid)) == NULL) {
193 X509error(X509_R_UNKNOWN_NID);
194 return NULL;
195 }
196
197 return X509_EXTENSION_create_by_OBJ(out_ext, obj, critical, data);
198}
199LCRYPTO_ALIAS(X509_EXTENSION_create_by_NID);
200
201X509_EXTENSION *
202X509_EXTENSION_create_by_OBJ(X509_EXTENSION **out_ext, const ASN1_OBJECT *obj,
203 int critical, ASN1_OCTET_STRING *data)
204{
205 X509_EXTENSION *ext;
206
207 if (out_ext == NULL || (ext = *out_ext) == NULL)
208 ext = X509_EXTENSION_new();
209 if (ext == NULL) {
210 X509error(ERR_R_MALLOC_FAILURE);
211 goto err;
212 }
213
214 if (!X509_EXTENSION_set_object(ext, obj))
215 goto err;
216 if (!X509_EXTENSION_set_critical(ext, critical))
217 goto err;
218 if (!X509_EXTENSION_set_data(ext, data))
219 goto err;
220
221 if (out_ext != NULL)
222 *out_ext = ext;
223
224 return ext;
225
226 err:
227 if (out_ext == NULL || ext != *out_ext)
228 X509_EXTENSION_free(ext);
229
230 return NULL;
231}
232LCRYPTO_ALIAS(X509_EXTENSION_create_by_OBJ);
233
234int
235X509_EXTENSION_set_object(X509_EXTENSION *ext, const ASN1_OBJECT *obj)
236{
237 if (ext == NULL || obj == NULL)
238 return 0;
239
240 ASN1_OBJECT_free(ext->object);
241 return (ext->object = OBJ_dup(obj)) != NULL;
242}
243LCRYPTO_ALIAS(X509_EXTENSION_set_object);
244
245int
246X509_EXTENSION_set_critical(X509_EXTENSION *ext, int critical)
247{
248 if (ext == NULL)
249 return 0;
250
251 ext->critical = critical ? 0xFF : -1;
252
253 return 1;
254}
255LCRYPTO_ALIAS(X509_EXTENSION_set_critical);
256
257int
258X509_EXTENSION_set_data(X509_EXTENSION *ext, ASN1_OCTET_STRING *data)
259{
260 if (ext == NULL)
261 return 0;
262
263 return ASN1_STRING_set(ext->value, data->data, data->length);
264}
265LCRYPTO_ALIAS(X509_EXTENSION_set_data);
266
267ASN1_OBJECT *
268X509_EXTENSION_get_object(X509_EXTENSION *ext)
269{
270 if (ext == NULL)
271 return NULL;
272
273 return ext->object;
274}
275LCRYPTO_ALIAS(X509_EXTENSION_get_object);
276
277ASN1_OCTET_STRING *
278X509_EXTENSION_get_data(X509_EXTENSION *ext)
279{
280 if (ext == NULL)
281 return NULL;
282
283 return ext->value;
284}
285LCRYPTO_ALIAS(X509_EXTENSION_get_data);
286
287int
288X509_EXTENSION_get_critical(const X509_EXTENSION *ext)
289{
290 if (ext == NULL)
291 return 0;
292
293 return ext->critical > 0;
294}
295LCRYPTO_ALIAS(X509_EXTENSION_get_critical);
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c
deleted file mode 100644
index f25e2b3f15..0000000000
--- a/src/lib/libcrypto/x509/x509_verify.c
+++ /dev/null
@@ -1,1288 +0,0 @@
1/* $OpenBSD: x509_verify.c,v 1.73 2025/02/08 10:12:00 tb Exp $ */
2/*
3 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* x509_verify - inspired by golang's crypto/x509.Verify */
19
20#include <errno.h>
21#include <stdio.h>
22#include <string.h>
23#include <time.h>
24#include <unistd.h>
25
26#include <openssl/safestack.h>
27#include <openssl/x509.h>
28#include <openssl/x509v3.h>
29
30#include "asn1_local.h"
31#include "x509_internal.h"
32#include "x509_issuer_cache.h"
33
34static int x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert,
35 struct x509_verify_chain *current_chain);
36static int x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert,
37 char *name);
38static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
39 struct x509_verify_chain *current_chain, int full_chain, char *name);
40static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert,
41 size_t depth, int error, int ok);
42static void x509_verify_chain_free(struct x509_verify_chain *chain);
43
44/*
45 * Parse an asn1 to a representable time_t as per RFC 5280 rules.
46 * Returns -1 if that can't be done for any reason.
47 */
48int
49x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notAfter,
50 time_t *out)
51{
52 struct tm tm = { 0 };
53 int type;
54
55 if (atime == NULL)
56 return 0;
57
58 type = ASN1_time_parse(atime->data, atime->length, &tm, atime->type);
59 if (type == -1)
60 return 0;
61
62 /* RFC 5280 section 4.1.2.5 */
63 if (tm.tm_year < 150 && type != V_ASN1_UTCTIME)
64 return 0;
65 if (tm.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME)
66 return 0;
67
68 if (notAfter) {
69 /*
70 * If we are a completely broken operating system with a
71 * 32 bit time_t, and we have been told this is a notAfter
72 * date, limit the date to a 32 bit representable value.
73 */
74 if (!ASN1_time_tm_clamp_notafter(&tm))
75 return 0;
76 }
77
78 /*
79 * Defensively fail if the time string is not representable as
80 * a time_t. A time_t must be sane if you care about times after
81 * Jan 19 2038.
82 */
83 return asn1_time_tm_to_time_t(&tm, out);
84}
85
86struct x509_verify_chain *
87x509_verify_chain_new(void)
88{
89 struct x509_verify_chain *chain;
90
91 if ((chain = calloc(1, sizeof(*chain))) == NULL)
92 goto err;
93 if ((chain->certs = sk_X509_new_null()) == NULL)
94 goto err;
95 if ((chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS,
96 sizeof(int))) == NULL)
97 goto err;
98 if ((chain->names =
99 x509_constraints_names_new(X509_VERIFY_MAX_CHAIN_NAMES)) == NULL)
100 goto err;
101
102 return chain;
103 err:
104 x509_verify_chain_free(chain);
105 return NULL;
106}
107
108static void
109x509_verify_chain_clear(struct x509_verify_chain *chain)
110{
111 sk_X509_pop_free(chain->certs, X509_free);
112 chain->certs = NULL;
113 free(chain->cert_errors);
114 chain->cert_errors = NULL;
115 x509_constraints_names_free(chain->names);
116 chain->names = NULL;
117}
118
119static void
120x509_verify_chain_free(struct x509_verify_chain *chain)
121{
122 if (chain == NULL)
123 return;
124 x509_verify_chain_clear(chain);
125 free(chain);
126}
127
128static struct x509_verify_chain *
129x509_verify_chain_dup(struct x509_verify_chain *chain)
130{
131 struct x509_verify_chain *new_chain;
132
133 if ((new_chain = calloc(1, sizeof(*chain))) == NULL)
134 goto err;
135 if ((new_chain->certs = X509_chain_up_ref(chain->certs)) == NULL)
136 goto err;
137 if ((new_chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS,
138 sizeof(int))) == NULL)
139 goto err;
140 memcpy(new_chain->cert_errors, chain->cert_errors,
141 X509_VERIFY_MAX_CHAIN_CERTS * sizeof(int));
142 if ((new_chain->names =
143 x509_constraints_names_dup(chain->names)) == NULL)
144 goto err;
145 return(new_chain);
146 err:
147 x509_verify_chain_free(new_chain);
148 return NULL;
149}
150
151static int
152x509_verify_chain_append(struct x509_verify_chain *chain, X509 *cert,
153 int *error)
154{
155 int verify_err = X509_V_ERR_UNSPECIFIED;
156 size_t idx;
157
158 if (!x509_constraints_extract_names(chain->names, cert,
159 sk_X509_num(chain->certs) == 0, &verify_err)) {
160 *error = verify_err;
161 return 0;
162 }
163
164 X509_up_ref(cert);
165 if (!sk_X509_push(chain->certs, cert)) {
166 X509_free(cert);
167 *error = X509_V_ERR_OUT_OF_MEM;
168 return 0;
169 }
170
171 idx = sk_X509_num(chain->certs) - 1;
172 chain->cert_errors[idx] = *error;
173
174 /*
175 * We've just added the issuer for the previous certificate,
176 * clear its error if appropriate.
177 */
178 if (idx > 1 && chain->cert_errors[idx - 1] ==
179 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
180 chain->cert_errors[idx - 1] = X509_V_OK;
181
182 return 1;
183}
184
185static X509 *
186x509_verify_chain_last(struct x509_verify_chain *chain)
187{
188 int last;
189
190 if (chain->certs == NULL)
191 return NULL;
192 if ((last = sk_X509_num(chain->certs) - 1) < 0)
193 return NULL;
194 return sk_X509_value(chain->certs, last);
195}
196
197X509 *
198x509_verify_chain_leaf(struct x509_verify_chain *chain)
199{
200 if (chain->certs == NULL)
201 return NULL;
202 return sk_X509_value(chain->certs, 0);
203}
204
205static void
206x509_verify_ctx_reset(struct x509_verify_ctx *ctx)
207{
208 size_t i;
209
210 for (i = 0; i < ctx->chains_count; i++)
211 x509_verify_chain_free(ctx->chains[i]);
212 sk_X509_pop_free(ctx->saved_error_chain, X509_free);
213 ctx->saved_error = 0;
214 ctx->saved_error_depth = 0;
215 ctx->error = 0;
216 ctx->error_depth = 0;
217 ctx->chains_count = 0;
218 ctx->sig_checks = 0;
219 ctx->check_time = NULL;
220}
221
222static void
223x509_verify_ctx_clear(struct x509_verify_ctx *ctx)
224{
225 x509_verify_ctx_reset(ctx);
226 sk_X509_pop_free(ctx->intermediates, X509_free);
227 free(ctx->chains);
228
229}
230
231static int
232x509_verify_cert_cache_extensions(X509 *cert)
233{
234 return x509v3_cache_extensions(cert);
235}
236
237static int
238x509_verify_cert_self_signed(X509 *cert)
239{
240 return (cert->ex_flags & EXFLAG_SS) ? 1 : 0;
241}
242
243/* XXX beck - clean up this mess of is_root */
244static int
245x509_verify_check_chain_end(X509 *cert, int full_chain)
246{
247 if (full_chain)
248 return x509_verify_cert_self_signed(cert);
249 return 1;
250}
251
252static int
253x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert,
254 int full_chain)
255{
256 X509 *match = NULL;
257 int i;
258
259 if (!x509_verify_cert_cache_extensions(cert))
260 return 0;
261
262 /* Check by lookup if we have a legacy xsc */
263 if (ctx->xsc != NULL) {
264 /*
265 * "alternative" lookup method, using the "trusted" stack in the
266 * xsc as the source for roots.
267 */
268 if (ctx->xsc->trusted != NULL) {
269 for (i = 0; i < sk_X509_num(ctx->xsc->trusted); i++) {
270 if (X509_cmp(sk_X509_value(ctx->xsc->trusted,
271 i), cert) == 0)
272 return x509_verify_check_chain_end(cert,
273 full_chain);
274 }
275 }
276 if ((match = x509_vfy_lookup_cert_match(ctx->xsc,
277 cert)) != NULL) {
278 X509_free(match);
279 return x509_verify_check_chain_end(cert, full_chain);
280 }
281 } else {
282 /* Check the provided roots */
283 for (i = 0; i < sk_X509_num(ctx->roots); i++) {
284 if (X509_cmp(sk_X509_value(ctx->roots, i), cert) == 0)
285 return x509_verify_check_chain_end(cert,
286 full_chain);
287 }
288 }
289
290 return 0;
291}
292
293static int
294x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx *ctx,
295 struct x509_verify_chain *chain, int set_error, int is_trusted)
296{
297 size_t num_untrusted;
298 int i;
299
300 if (ctx->xsc == NULL)
301 return 1;
302
303 /*
304 * XXX num_untrusted is the number of untrusted certs at the
305 * bottom of the chain. This works now since we stop at the first
306 * trusted cert. This will need fixing once we allow more than one
307 * trusted certificate.
308 */
309 num_untrusted = sk_X509_num(chain->certs);
310 if (is_trusted && num_untrusted > 0)
311 num_untrusted--;
312 ctx->xsc->num_untrusted = num_untrusted;
313
314 sk_X509_pop_free(ctx->xsc->chain, X509_free);
315 ctx->xsc->chain = X509_chain_up_ref(chain->certs);
316 if (ctx->xsc->chain == NULL)
317 return x509_verify_cert_error(ctx, NULL, 0,
318 X509_V_ERR_OUT_OF_MEM, 0);
319
320 if (set_error) {
321 ctx->xsc->error = X509_V_OK;
322 ctx->xsc->error_depth = 0;
323 for (i = 0; i < sk_X509_num(chain->certs); i++) {
324 if (chain->cert_errors[i] != X509_V_OK) {
325 ctx->xsc->error = chain->cert_errors[i];
326 ctx->xsc->error_depth = i;
327 break;
328 }
329 }
330 }
331
332 return 1;
333}
334
335
336/*
337 * Save the error state and unvalidated chain off of the xsc for
338 * later.
339 */
340static int
341x509_verify_ctx_save_xsc_error(struct x509_verify_ctx *ctx)
342{
343 if (ctx->xsc != NULL && ctx->xsc->chain != NULL) {
344 sk_X509_pop_free(ctx->saved_error_chain, X509_free);
345 ctx->saved_error_chain = X509_chain_up_ref(ctx->xsc->chain);
346 if (ctx->saved_error_chain == NULL)
347 return x509_verify_cert_error(ctx, NULL, 0,
348 X509_V_ERR_OUT_OF_MEM, 0);
349 ctx->saved_error = ctx->xsc->error;
350 ctx->saved_error_depth = ctx->xsc->error_depth;
351 }
352 return 1;
353}
354
355/*
356 * Restore the saved error state and unvalidated chain to the xsc
357 * if we do not have a validated chain.
358 */
359static int
360x509_verify_ctx_restore_xsc_error(struct x509_verify_ctx *ctx)
361{
362 if (ctx->xsc != NULL && ctx->chains_count == 0 &&
363 ctx->saved_error_chain != NULL) {
364 sk_X509_pop_free(ctx->xsc->chain, X509_free);
365 ctx->xsc->chain = X509_chain_up_ref(ctx->saved_error_chain);
366 if (ctx->xsc->chain == NULL)
367 return x509_verify_cert_error(ctx, NULL, 0,
368 X509_V_ERR_OUT_OF_MEM, 0);
369 ctx->xsc->error = ctx->saved_error;
370 ctx->xsc->error_depth = ctx->saved_error_depth;
371 }
372 return 1;
373}
374
375/* Perform legacy style validation of a chain */
376static int
377x509_verify_ctx_validate_legacy_chain(struct x509_verify_ctx *ctx,
378 struct x509_verify_chain *chain, size_t depth)
379{
380 int ret = 0, trust;
381
382 if (ctx->xsc == NULL)
383 return 1;
384
385 /*
386 * If we have a legacy xsc, choose a validated chain, and
387 * apply the extensions, revocation, and policy checks just
388 * like the legacy code did. We do this here instead of as
389 * building the chains to more easily support the callback and
390 * the bewildering array of VERIFY_PARAM knobs that are there
391 * for the fiddling.
392 */
393
394 /* These may be set in one of the following calls. */
395 ctx->xsc->error = X509_V_OK;
396 ctx->xsc->error_depth = 0;
397
398 if (!x509_verify_ctx_set_xsc_chain(ctx, chain, 0, 1))
399 goto err;
400
401 /*
402 * Call the legacy code to walk the chain and check trust
403 * in the legacy way to handle partial chains and get the
404 * callback fired correctly.
405 */
406 trust = x509_vfy_check_trust(ctx->xsc);
407 if (trust == X509_TRUST_REJECTED)
408 goto err; /* callback was called in x509_vfy_check_trust */
409 if (trust != X509_TRUST_TRUSTED) {
410 /* NOTREACHED */
411 goto err; /* should not happen if we get in here - abort? */
412 }
413
414 /*
415 * XXX currently this duplicates some work done in chain
416 * build, but we keep it here until we have feature parity
417 */
418 if (!x509_vfy_check_chain_extensions(ctx->xsc))
419 goto err;
420
421#ifndef OPENSSL_NO_RFC3779
422 if (!X509v3_asid_validate_path(ctx->xsc))
423 goto err;
424
425 if (!X509v3_addr_validate_path(ctx->xsc))
426 goto err;
427#endif
428
429 if (!x509_vfy_check_security_level(ctx->xsc))
430 goto err;
431
432 if (!x509_constraints_chain(ctx->xsc->chain,
433 &ctx->xsc->error, &ctx->xsc->error_depth)) {
434 X509 *cert = sk_X509_value(ctx->xsc->chain, depth);
435 if (!x509_verify_cert_error(ctx, cert,
436 ctx->xsc->error_depth, ctx->xsc->error, 0))
437 goto err;
438 }
439
440 if (!x509_vfy_check_revocation(ctx->xsc))
441 goto err;
442
443 if (!x509_vfy_check_policy(ctx->xsc))
444 goto err;
445
446 ret = 1;
447
448 err:
449 /*
450 * The above checks may have set ctx->xsc->error and
451 * ctx->xsc->error_depth - save these for later on.
452 */
453 if (ctx->xsc->error != X509_V_OK) {
454 if (ctx->xsc->error_depth < 0 ||
455 ctx->xsc->error_depth >= X509_VERIFY_MAX_CHAIN_CERTS)
456 return 0;
457 chain->cert_errors[ctx->xsc->error_depth] =
458 ctx->xsc->error;
459 ctx->error_depth = ctx->xsc->error_depth;
460 }
461
462 return ret;
463}
464
465/* Add a validated chain to our list of valid chains */
466static int
467x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx,
468 struct x509_verify_chain *chain, char *name)
469{
470 size_t depth;
471 X509 *last = x509_verify_chain_last(chain);
472 X509 *leaf = x509_verify_chain_leaf(chain);
473
474 depth = sk_X509_num(chain->certs);
475 if (depth > 0)
476 depth--;
477
478 if (ctx->chains_count >= ctx->max_chains)
479 return x509_verify_cert_error(ctx, last, depth,
480 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0);
481
482 /* Clear a get issuer failure for a root certificate. */
483 if (chain->cert_errors[depth] ==
484 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
485 chain->cert_errors[depth] = X509_V_OK;
486
487 if (!x509_verify_ctx_validate_legacy_chain(ctx, chain, depth))
488 return 0;
489
490 /* Verify the leaf certificate and store any resulting error. */
491 if (!x509_verify_cert_valid(ctx, leaf, NULL))
492 return 0;
493 if (!x509_verify_cert_hostname(ctx, leaf, name))
494 return 0;
495 if (ctx->error_depth == 0 &&
496 ctx->error != X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY)
497 chain->cert_errors[0] = ctx->error;
498
499 /*
500 * In the non-legacy code, extensions and purpose are dealt
501 * with as the chain is built.
502 *
503 * The non-legacy api returns multiple chains but does not do
504 * any revocation checking (it must be done by the caller on
505 * any chain they wish to use)
506 */
507
508 if ((ctx->chains[ctx->chains_count] = x509_verify_chain_dup(chain)) ==
509 NULL) {
510 return x509_verify_cert_error(ctx, last, depth,
511 X509_V_ERR_OUT_OF_MEM, 0);
512 }
513 ctx->chains_count++;
514
515 ctx->error = X509_V_OK;
516 ctx->error_depth = depth;
517
518 return 1;
519}
520
521static int
522x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent,
523 X509 *child)
524{
525 if (!x509_verify_cert_cache_extensions(parent))
526 return 0;
527 if (ctx->xsc != NULL)
528 return (ctx->xsc->check_issued(ctx->xsc, child, parent));
529
530 /* XXX key usage */
531 return X509_check_issued(parent, child) == X509_V_OK;
532}
533
534/* Matches x509_crl_verify_parent_signature() */
535static int
536x509_verify_parent_signature(X509 *parent, X509 *child, int *error)
537{
538 EVP_PKEY *pkey;
539 int cached;
540 int ret = 0;
541
542 /* Use cached value if we have it */
543 if ((cached = x509_issuer_cache_find(parent->hash, child->hash)) >= 0) {
544 if (cached == 0)
545 *error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
546 return cached;
547 }
548
549 /* Check signature. Did parent sign child? */
550 if ((pkey = X509_get0_pubkey(parent)) == NULL) {
551 *error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
552 return 0;
553 }
554 if (X509_verify(child, pkey) <= 0)
555 *error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
556 else
557 ret = 1;
558
559 /* Add result to cache */
560 x509_issuer_cache_add(parent->hash, child->hash, ret);
561
562 return ret;
563}
564
565static int
566x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
567 int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain,
568 int full_chain, char *name)
569{
570 int depth = sk_X509_num(current_chain->certs);
571 struct x509_verify_chain *new_chain;
572 int i;
573
574 /* Fail if the certificate is already in the chain */
575 for (i = 0; i < sk_X509_num(current_chain->certs); i++) {
576 if (X509_cmp(sk_X509_value(current_chain->certs, i),
577 candidate) == 0)
578 return 0;
579 }
580
581 if (ctx->sig_checks++ > X509_VERIFY_MAX_SIGCHECKS) {
582 /* don't allow callback to override safety check */
583 (void) x509_verify_cert_error(ctx, candidate, depth,
584 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0);
585 return 0;
586 }
587
588 if (!x509_verify_parent_signature(candidate, cert, &ctx->error)) {
589 if (!x509_verify_cert_error(ctx, candidate, depth,
590 ctx->error, 0))
591 return 0;
592 }
593
594 if (!x509_verify_cert_valid(ctx, candidate, current_chain))
595 return 0;
596
597 /* candidate is good, add it to a copy of the current chain */
598 if ((new_chain = x509_verify_chain_dup(current_chain)) == NULL) {
599 x509_verify_cert_error(ctx, candidate, depth,
600 X509_V_ERR_OUT_OF_MEM, 0);
601 return 0;
602 }
603 if (!x509_verify_chain_append(new_chain, candidate, &ctx->error)) {
604 x509_verify_cert_error(ctx, candidate, depth, ctx->error, 0);
605 x509_verify_chain_free(new_chain);
606 return 0;
607 }
608
609 /*
610 * If candidate is a trusted root, we have a validated chain,
611 * so we save it. Otherwise, recurse until we find a root or
612 * give up.
613 */
614 if (is_root_cert) {
615 if (!x509_verify_ctx_set_xsc_chain(ctx, new_chain, 0, 1)) {
616 x509_verify_chain_free(new_chain);
617 return 0;
618 }
619 if (!x509_verify_ctx_add_chain(ctx, new_chain, name)) {
620 x509_verify_chain_free(new_chain);
621 return 0;
622 }
623 goto done;
624 }
625
626 x509_verify_build_chains(ctx, candidate, new_chain, full_chain, name);
627
628 done:
629 x509_verify_chain_free(new_chain);
630 return 1;
631}
632
633static int
634x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, size_t depth,
635 int error, int ok)
636{
637 ctx->error = error;
638 ctx->error_depth = depth;
639 if (ctx->xsc != NULL) {
640 ctx->xsc->error = error;
641 ctx->xsc->error_depth = depth;
642 ctx->xsc->current_cert = cert;
643 return ctx->xsc->verify_cb(ok, ctx->xsc);
644 }
645 return ok;
646}
647
648static void
649x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
650 struct x509_verify_chain *current_chain, int full_chain, char *name)
651{
652 X509 *candidate;
653 int i, depth, count, ret, is_root;
654
655 /*
656 * If we are finding chains with an xsc, just stop after we have
657 * one chain, there's no point in finding more, it just exercises
658 * the potentially buggy callback processing in the calling software.
659 */
660 if (ctx->xsc != NULL && ctx->chains_count > 0)
661 return;
662
663 depth = sk_X509_num(current_chain->certs);
664 if (depth > 0)
665 depth--;
666
667 if (depth >= ctx->max_depth &&
668 !x509_verify_cert_error(ctx, cert, depth,
669 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0))
670 return;
671
672 count = ctx->chains_count;
673
674 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
675 ctx->error_depth = depth;
676
677 if (ctx->saved_error != 0)
678 ctx->error = ctx->saved_error;
679 if (ctx->saved_error_depth != 0)
680 ctx->error_depth = ctx->saved_error_depth;
681
682 if (ctx->xsc != NULL) {
683 /*
684 * Long ago experiments at Muppet labs resulted in a
685 * situation where software not only sees these errors
686 * but forced developers to expect them in certain cases.
687 * so we must mimic this awfulness for the legacy case.
688 */
689 if (cert->ex_flags & EXFLAG_SS)
690 ctx->error = (depth == 0) ?
691 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
692 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
693 }
694
695 /* Check for legacy mode roots */
696 if (ctx->xsc != NULL) {
697 if ((ret = ctx->xsc->get_issuer(&candidate, ctx->xsc, cert)) < 0) {
698 x509_verify_cert_error(ctx, cert, depth,
699 X509_V_ERR_STORE_LOOKUP, 0);
700 return;
701 }
702 if (ret > 0) {
703 if (x509_verify_potential_parent(ctx, candidate, cert)) {
704 is_root = x509_verify_check_chain_end(candidate,
705 full_chain);
706 x509_verify_consider_candidate(ctx, cert,
707 is_root, candidate, current_chain,
708 full_chain, name);
709 }
710 X509_free(candidate);
711 }
712 } else {
713 /* Check to see if we have a trusted root issuer. */
714 for (i = 0; i < sk_X509_num(ctx->roots); i++) {
715 candidate = sk_X509_value(ctx->roots, i);
716 if (x509_verify_potential_parent(ctx, candidate, cert)) {
717 is_root = x509_verify_check_chain_end(candidate,
718 full_chain);
719 x509_verify_consider_candidate(ctx, cert,
720 is_root, candidate, current_chain,
721 full_chain, name);
722 }
723 }
724 }
725
726 /* Check intermediates after checking roots */
727 if (ctx->intermediates != NULL) {
728 for (i = 0; i < sk_X509_num(ctx->intermediates); i++) {
729 candidate = sk_X509_value(ctx->intermediates, i);
730 if (x509_verify_potential_parent(ctx, candidate, cert)) {
731 x509_verify_consider_candidate(ctx, cert,
732 0, candidate, current_chain,
733 full_chain, name);
734 }
735 }
736 }
737
738 if (ctx->chains_count > count) {
739 if (ctx->xsc != NULL) {
740 ctx->xsc->error = X509_V_OK;
741 ctx->xsc->error_depth = depth;
742 ctx->xsc->current_cert = cert;
743 }
744 } else if (ctx->error_depth == depth) {
745 if (!x509_verify_ctx_set_xsc_chain(ctx, current_chain, 0, 0))
746 return;
747 }
748}
749
750static int
751x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert, char *name)
752{
753 char *candidate;
754 size_t len;
755
756 if (name == NULL) {
757 if (ctx->xsc != NULL) {
758 int ret;
759
760 if ((ret = x509_vfy_check_id(ctx->xsc)) == 0)
761 ctx->error = ctx->xsc->error;
762 return ret;
763 }
764 return 1;
765 }
766 if ((candidate = strdup(name)) == NULL) {
767 ctx->error = X509_V_ERR_OUT_OF_MEM;
768 goto err;
769 }
770 if ((len = strlen(candidate)) < 1) {
771 ctx->error = X509_V_ERR_UNSPECIFIED; /* XXX */
772 goto err;
773 }
774
775 /* IP addresses may be written in [ ]. */
776 if (candidate[0] == '[' && candidate[len - 1] == ']') {
777 candidate[len - 1] = '\0';
778 if (X509_check_ip_asc(cert, candidate + 1, 0) <= 0) {
779 ctx->error = X509_V_ERR_IP_ADDRESS_MISMATCH;
780 goto err;
781 }
782 } else {
783 int flags = 0;
784
785 if (ctx->xsc == NULL)
786 flags = X509_CHECK_FLAG_NEVER_CHECK_SUBJECT;
787
788 if (X509_check_host(cert, candidate, len, flags, NULL) <= 0) {
789 ctx->error = X509_V_ERR_HOSTNAME_MISMATCH;
790 goto err;
791 }
792 }
793 free(candidate);
794 return 1;
795 err:
796 free(candidate);
797 return x509_verify_cert_error(ctx, cert, 0, ctx->error, 0);
798}
799
800static int
801x509_verify_set_check_time(struct x509_verify_ctx *ctx)
802{
803 if (ctx->xsc != NULL) {
804 if (ctx->xsc->param->flags & X509_V_FLAG_USE_CHECK_TIME) {
805 ctx->check_time = &ctx->xsc->param->check_time;
806 return 1;
807 }
808 if (ctx->xsc->param->flags & X509_V_FLAG_NO_CHECK_TIME)
809 return 0;
810 }
811
812 ctx->check_time = NULL;
813 return 1;
814}
815
816static int
817x509_verify_cert_times(X509 *cert, time_t *cmp_time, int *error)
818{
819 time_t when, not_before, not_after;
820
821 if (cmp_time == NULL)
822 when = time(NULL);
823 else
824 when = *cmp_time;
825
826 if (!x509_verify_asn1_time_to_time_t(X509_get_notBefore(cert), 0,
827 &not_before)) {
828 *error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
829 return 0;
830 }
831 if (when < not_before) {
832 *error = X509_V_ERR_CERT_NOT_YET_VALID;
833 return 0;
834 }
835 if (!x509_verify_asn1_time_to_time_t(X509_get_notAfter(cert), 1,
836 &not_after)) {
837 *error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
838 return 0;
839 }
840 if (when > not_after) {
841 *error = X509_V_ERR_CERT_HAS_EXPIRED;
842 return 0;
843 }
844
845 return 1;
846}
847
848static int
849x509_verify_validate_constraints(X509 *cert,
850 struct x509_verify_chain *current_chain, int *error)
851{
852 struct x509_constraints_names *excluded = NULL;
853 struct x509_constraints_names *permitted = NULL;
854 int err = X509_V_ERR_UNSPECIFIED;
855
856 if (current_chain == NULL)
857 return 1;
858
859 if (cert->nc != NULL) {
860 if ((permitted = x509_constraints_names_new(
861 X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) {
862 err = X509_V_ERR_OUT_OF_MEM;
863 goto err;
864 }
865 if ((excluded = x509_constraints_names_new(
866 X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) {
867 err = X509_V_ERR_OUT_OF_MEM;
868 goto err;
869 }
870 if (!x509_constraints_extract_constraints(cert,
871 permitted, excluded, &err))
872 goto err;
873 if (!x509_constraints_check(current_chain->names,
874 permitted, excluded, &err))
875 goto err;
876 x509_constraints_names_free(excluded);
877 x509_constraints_names_free(permitted);
878 }
879
880 return 1;
881 err:
882 *error = err;
883 x509_constraints_names_free(excluded);
884 x509_constraints_names_free(permitted);
885 return 0;
886}
887
888static int
889x509_verify_cert_extensions(struct x509_verify_ctx *ctx, X509 *cert, int need_ca)
890{
891 if (!x509_verify_cert_cache_extensions(cert)) {
892 ctx->error = X509_V_ERR_UNSPECIFIED;
893 return 0;
894 }
895
896 if (ctx->xsc != NULL)
897 return 1; /* legacy is checked after chain is built */
898
899 if (cert->ex_flags & EXFLAG_CRITICAL) {
900 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
901 return 0;
902 }
903 /* No we don't care about v1, netscape, and other ancient silliness */
904 if (need_ca && (!(cert->ex_flags & EXFLAG_BCONS) &&
905 (cert->ex_flags & EXFLAG_CA))) {
906 ctx->error = X509_V_ERR_INVALID_CA;
907 return 0;
908 }
909 if (ctx->purpose > 0 && X509_check_purpose(cert, ctx->purpose, need_ca)) {
910 ctx->error = X509_V_ERR_INVALID_PURPOSE;
911 return 0;
912 }
913
914 return 1;
915}
916
917/* Validate that cert is a possible candidate to append to current_chain */
918static int
919x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert,
920 struct x509_verify_chain *current_chain)
921{
922 X509 *issuer_candidate;
923 int should_be_ca = current_chain != NULL;
924 size_t depth = 0;
925
926 if (current_chain != NULL)
927 depth = sk_X509_num(current_chain->certs);
928
929 if (!x509_verify_cert_extensions(ctx, cert, should_be_ca))
930 return 0;
931
932 if (should_be_ca) {
933 issuer_candidate = x509_verify_chain_last(current_chain);
934 if (issuer_candidate != NULL &&
935 !X509_check_issued(issuer_candidate, cert))
936 if (!x509_verify_cert_error(ctx, cert, depth,
937 X509_V_ERR_SUBJECT_ISSUER_MISMATCH, 0))
938 return 0;
939 }
940
941 if (x509_verify_set_check_time(ctx)) {
942 if (!x509_verify_cert_times(cert, ctx->check_time,
943 &ctx->error)) {
944 if (!x509_verify_cert_error(ctx, cert, depth,
945 ctx->error, 0))
946 return 0;
947 }
948 }
949
950 if (!x509_verify_validate_constraints(cert, current_chain,
951 &ctx->error) && !x509_verify_cert_error(ctx, cert, depth,
952 ctx->error, 0))
953 return 0;
954
955 return 1;
956}
957
958struct x509_verify_ctx *
959x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc)
960{
961 struct x509_verify_ctx *ctx;
962 size_t max_depth;
963
964 if (xsc == NULL)
965 return NULL;
966
967 if ((ctx = x509_verify_ctx_new(NULL)) == NULL)
968 return NULL;
969
970 ctx->xsc = xsc;
971
972 if (xsc->untrusted &&
973 (ctx->intermediates = X509_chain_up_ref(xsc->untrusted)) == NULL)
974 goto err;
975
976 max_depth = X509_VERIFY_MAX_CHAIN_CERTS;
977 if (xsc->param->depth > 0 && xsc->param->depth < X509_VERIFY_MAX_CHAIN_CERTS)
978 max_depth = xsc->param->depth;
979 if (!x509_verify_ctx_set_max_depth(ctx, max_depth))
980 goto err;
981
982 return ctx;
983 err:
984 x509_verify_ctx_free(ctx);
985 return NULL;
986}
987
988/* Public API */
989
990struct x509_verify_ctx *
991x509_verify_ctx_new(STACK_OF(X509) *roots)
992{
993 struct x509_verify_ctx *ctx;
994
995 if ((ctx = calloc(1, sizeof(struct x509_verify_ctx))) == NULL)
996 return NULL;
997
998 if (roots != NULL) {
999 if ((ctx->roots = X509_chain_up_ref(roots)) == NULL)
1000 goto err;
1001 } else {
1002 if ((ctx->roots = sk_X509_new_null()) == NULL)
1003 goto err;
1004 }
1005
1006 ctx->max_depth = X509_VERIFY_MAX_CHAIN_CERTS;
1007 ctx->max_chains = X509_VERIFY_MAX_CHAINS;
1008 ctx->max_sigs = X509_VERIFY_MAX_SIGCHECKS;
1009
1010 if ((ctx->chains = calloc(X509_VERIFY_MAX_CHAINS,
1011 sizeof(*ctx->chains))) == NULL)
1012 goto err;
1013
1014 return ctx;
1015 err:
1016 x509_verify_ctx_free(ctx);
1017 return NULL;
1018}
1019
1020void
1021x509_verify_ctx_free(struct x509_verify_ctx *ctx)
1022{
1023 if (ctx == NULL)
1024 return;
1025 sk_X509_pop_free(ctx->roots, X509_free);
1026 x509_verify_ctx_clear(ctx);
1027 free(ctx);
1028}
1029
1030int
1031x509_verify_ctx_set_max_depth(struct x509_verify_ctx *ctx, size_t max)
1032{
1033 if (max < 1 || max > X509_VERIFY_MAX_CHAIN_CERTS)
1034 return 0;
1035 ctx->max_depth = max;
1036 return 1;
1037}
1038
1039int
1040x509_verify_ctx_set_max_chains(struct x509_verify_ctx *ctx, size_t max)
1041{
1042 if (max < 1 || max > X509_VERIFY_MAX_CHAINS)
1043 return 0;
1044 ctx->max_chains = max;
1045 return 1;
1046}
1047
1048int
1049x509_verify_ctx_set_max_signatures(struct x509_verify_ctx *ctx, size_t max)
1050{
1051 if (max < 1 || max > 100000)
1052 return 0;
1053 ctx->max_sigs = max;
1054 return 1;
1055}
1056
1057int
1058x509_verify_ctx_set_purpose(struct x509_verify_ctx *ctx, int purpose)
1059{
1060 if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX)
1061 return 0;
1062 ctx->purpose = purpose;
1063 return 1;
1064}
1065
1066int
1067x509_verify_ctx_set_intermediates(struct x509_verify_ctx *ctx,
1068 STACK_OF(X509) *intermediates)
1069{
1070 if ((ctx->intermediates = X509_chain_up_ref(intermediates)) == NULL)
1071 return 0;
1072 return 1;
1073}
1074
1075const char *
1076x509_verify_ctx_error_string(struct x509_verify_ctx *ctx)
1077{
1078 return X509_verify_cert_error_string(ctx->error);
1079}
1080
1081size_t
1082x509_verify_ctx_error_depth(struct x509_verify_ctx *ctx)
1083{
1084 return ctx->error_depth;
1085}
1086
1087STACK_OF(X509) *
1088x509_verify_ctx_chain(struct x509_verify_ctx *ctx, size_t i)
1089{
1090 if (i >= ctx->chains_count)
1091 return NULL;
1092 return ctx->chains[i]->certs;
1093}
1094
1095size_t
1096x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
1097{
1098 struct x509_verify_chain *current_chain;
1099 int retry_chain_build, full_chain = 0;
1100
1101 if (ctx->roots == NULL || ctx->max_depth == 0) {
1102 ctx->error = X509_V_ERR_INVALID_CALL;
1103 goto err;
1104 }
1105
1106 if (ctx->xsc != NULL) {
1107 if (leaf != NULL || name != NULL) {
1108 ctx->error = X509_V_ERR_INVALID_CALL;
1109 goto err;
1110 }
1111 leaf = ctx->xsc->cert;
1112
1113 /* XXX */
1114 full_chain = 1;
1115 if (ctx->xsc->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
1116 full_chain = 0;
1117 /*
1118 * XXX
1119 * The legacy code expects the top level cert to be
1120 * there, even if we didn't find a chain. So put it
1121 * there, we will clobber it later if we find a valid
1122 * chain.
1123 */
1124 if ((ctx->xsc->chain = sk_X509_new_null()) == NULL) {
1125 ctx->error = X509_V_ERR_OUT_OF_MEM;
1126 goto err;
1127 }
1128 if (!X509_up_ref(leaf)) {
1129 ctx->error = X509_V_ERR_OUT_OF_MEM;
1130 goto err;
1131 }
1132 if (!sk_X509_push(ctx->xsc->chain, leaf)) {
1133 X509_free(leaf);
1134 ctx->error = X509_V_ERR_OUT_OF_MEM;
1135 goto err;
1136 }
1137 ctx->xsc->error_depth = 0;
1138 ctx->xsc->current_cert = leaf;
1139 }
1140
1141 if ((current_chain = x509_verify_chain_new()) == NULL) {
1142 ctx->error = X509_V_ERR_OUT_OF_MEM;
1143 goto err;
1144 }
1145
1146 /*
1147 * Add the leaf to the chain and try to build chains from it.
1148 * Note that unlike Go's verifier, we have not yet checked
1149 * anything about the leaf, This is intentional, so that we
1150 * report failures in chain building before we report problems
1151 * with the leaf.
1152 */
1153 if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) {
1154 x509_verify_chain_free(current_chain);
1155 goto err;
1156 }
1157 do {
1158 retry_chain_build = 0;
1159 if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) {
1160 if (!x509_verify_ctx_add_chain(ctx, current_chain,
1161 name)) {
1162 x509_verify_chain_free(current_chain);
1163 goto err;
1164 }
1165 } else {
1166 x509_verify_build_chains(ctx, leaf, current_chain,
1167 full_chain, name);
1168 if (full_chain && ctx->chains_count == 0) {
1169 /*
1170 * Save the error state from the xsc
1171 * at this point to put back on the
1172 * xsc in case we do not find a chain
1173 * that is trusted but not a full
1174 * chain to a self signed root. This
1175 * is because the unvalidated chain is
1176 * used by the autochain batshittery
1177 * on failure and will be needed for
1178 * that.
1179 */
1180 ctx->xsc->error_depth = ctx->error_depth;
1181 if (!x509_verify_ctx_save_xsc_error(ctx)) {
1182 x509_verify_chain_free(current_chain);
1183 goto err;
1184 }
1185 full_chain = 0;
1186 retry_chain_build = 1;
1187 }
1188 }
1189 } while (retry_chain_build);
1190
1191 x509_verify_chain_free(current_chain);
1192
1193 /*
1194 * Do the new verifier style return, where we don't have an xsc
1195 * that allows a crazy callback to turn invalid things into valid.
1196 */
1197 if (ctx->xsc == NULL) {
1198 /*
1199 * Safety net:
1200 * We could not find a validated chain, and for some reason do not
1201 * have an error set.
1202 */
1203 if (ctx->chains_count == 0 && ctx->error == X509_V_OK)
1204 ctx->error = X509_V_ERR_UNSPECIFIED;
1205
1206 /*
1207 * If we are not using an xsc, and have no possibility for the
1208 * crazy OpenSSL callback API changing the results of
1209 * validation steps (because the callback can make validation
1210 * proceed in the presence of invalid certs), any chains we
1211 * have here are correctly built and verified.
1212 */
1213 if (ctx->chains_count > 0)
1214 ctx->error = X509_V_OK;
1215
1216 return ctx->chains_count;
1217 }
1218
1219 /*
1220 * Otherwise we are doing compatibility with an xsc, which means that we
1221 * will have one chain, which might actually be a bogus chain because
1222 * the callback told us to ignore errors and proceed to build an invalid
1223 * chain. Possible return values from this include returning 1 with an
1224 * invalid chain and a value of xsc->error != X509_V_OK (It's tradition
1225 * that makes it ok).
1226 */
1227
1228 if (ctx->chains_count > 0) {
1229 /*
1230 * The chain we have using an xsc might not be a verified chain
1231 * if the callback perverted things while we built it to ignore
1232 * failures and proceed with chain building. We put this chain
1233 * and the error associated with it on the xsc.
1234 */
1235 if (!x509_verify_ctx_set_xsc_chain(ctx, ctx->chains[0], 1, 1))
1236 goto err;
1237
1238 /*
1239 * Call the callback for completion up our built
1240 * chain. The callback could still tell us to
1241 * fail. Since this chain might exist as the result of
1242 * callback doing perversions, we could still return
1243 * "success" with something other than X509_V_OK set
1244 * as the error.
1245 */
1246 if (!x509_vfy_callback_indicate_completion(ctx->xsc))
1247 goto err;
1248 } else {
1249 /*
1250 * We did not find a chain. Bring back the failure
1251 * case we wanted to the xsc if we saved one. If we
1252 * did not we should have just the leaf on the xsc.
1253 */
1254 if (!x509_verify_ctx_restore_xsc_error(ctx))
1255 goto err;
1256
1257 /*
1258 * Safety net, ensure we have an error set in the
1259 * failing case.
1260 */
1261 if (ctx->xsc->error == X509_V_OK) {
1262 if (ctx->error == X509_V_OK)
1263 ctx->error = X509_V_ERR_UNSPECIFIED;
1264 ctx->xsc->error = ctx->error;
1265 }
1266
1267 /*
1268 * Let the callback override the return value
1269 * at depth 0 if it chooses to
1270 */
1271 return ctx->xsc->verify_cb(0, ctx->xsc);
1272 }
1273
1274 /* We only ever find one chain in compat mode with an xsc. */
1275 return 1;
1276
1277 err:
1278 if (ctx->error == X509_V_OK)
1279 ctx->error = X509_V_ERR_UNSPECIFIED;
1280
1281 if (ctx->xsc != NULL) {
1282 if (ctx->xsc->error == X509_V_OK)
1283 ctx->xsc->error = X509_V_ERR_UNSPECIFIED;
1284 ctx->error = ctx->xsc->error;
1285 }
1286
1287 return 0;
1288}
diff --git a/src/lib/libcrypto/x509/x509_verify.h b/src/lib/libcrypto/x509/x509_verify.h
deleted file mode 100644
index d8d2cb0b5f..0000000000
--- a/src/lib/libcrypto/x509/x509_verify.h
+++ /dev/null
@@ -1,43 +0,0 @@
1/* $OpenBSD: x509_verify.h,v 1.2 2021/11/04 23:52:34 beck Exp $ */
2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17#ifndef HEADER_X509_VERIFY_H
18#define HEADER_X509_VERIFY_H
19
20#ifdef LIBRESSL_INTERNAL
21struct x509_verify_ctx;
22struct x509_verify_cert_info;
23typedef struct x509_verify_ctx X509_VERIFY_CTX;
24
25X509_VERIFY_CTX *x509_verify_ctx_new(STACK_OF(X509) *roots);
26void x509_verify_ctx_free(struct x509_verify_ctx *ctx);
27
28int x509_verify_ctx_set_max_depth(X509_VERIFY_CTX *ctx, size_t max);
29int x509_verify_ctx_set_max_chains(X509_VERIFY_CTX *ctx, size_t max);
30int x509_verify_ctx_set_max_signatures(X509_VERIFY_CTX *ctx, size_t max);
31int x509_verify_ctx_set_purpose(X509_VERIFY_CTX *ctx, int purpose_id);
32int x509_verify_ctx_set_intermediates(X509_VERIFY_CTX *ctx,
33 STACK_OF(X509) *intermediates);
34
35const char *x509_verify_ctx_error_string(X509_VERIFY_CTX *ctx);
36size_t x509_verify_ctx_error_depth(X509_VERIFY_CTX *ctx);
37
38STACK_OF(X509) *x509_verify_ctx_chain(X509_VERIFY_CTX *ctx, size_t chain);
39
40size_t x509_verify(X509_VERIFY_CTX *ctx, X509 *leaf, char *name);
41#endif
42
43#endif
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
deleted file mode 100644
index c93ae81bd8..0000000000
--- a/src/lib/libcrypto/x509/x509_vfy.c
+++ /dev/null
@@ -1,2602 +0,0 @@
1/* $OpenBSD: x509_vfy.c,v 1.147 2025/03/04 08:43:25 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <errno.h>
60#include <stdio.h>
61#include <string.h>
62#include <time.h>
63#include <unistd.h>
64
65#include <openssl/opensslconf.h>
66
67#include <openssl/asn1.h>
68#include <openssl/buffer.h>
69#include <openssl/crypto.h>
70#include <openssl/err.h>
71#include <openssl/evp.h>
72#include <openssl/lhash.h>
73#include <openssl/objects.h>
74#include <openssl/x509.h>
75#include <openssl/x509v3.h>
76
77#include "asn1_local.h"
78#include "x509_internal.h"
79#include "x509_issuer_cache.h"
80#include "x509_local.h"
81
82/* CRL score values */
83
84/* No unhandled critical extensions */
85
86#define CRL_SCORE_NOCRITICAL 0x100
87
88/* certificate is within CRL scope */
89
90#define CRL_SCORE_SCOPE 0x080
91
92/* CRL times valid */
93
94#define CRL_SCORE_TIME 0x040
95
96/* Issuer name matches certificate */
97
98#define CRL_SCORE_ISSUER_NAME 0x020
99
100/* If this score or above CRL is probably valid */
101
102#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
103
104/* CRL issuer is certificate issuer */
105
106#define CRL_SCORE_ISSUER_CERT 0x018
107
108/* CRL issuer is on certificate path */
109
110#define CRL_SCORE_SAME_PATH 0x008
111
112/* CRL issuer matches CRL AKID */
113
114#define CRL_SCORE_AKID 0x004
115
116/* Have a delta CRL with valid times */
117
118#define CRL_SCORE_TIME_DELTA 0x002
119
120static int x509_vfy_check_crl(X509_STORE_CTX *ctx, X509_CRL *crl);
121static int x509_vfy_cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
122
123static int null_callback(int ok, X509_STORE_CTX *e);
124static int check_issued(X509_STORE_CTX *ctx, X509 *subject, X509 *issuer);
125static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x,
126 int allow_expired);
127static int check_name_constraints(X509_STORE_CTX *ctx);
128static int check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth);
129
130static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
131 unsigned int *preasons, X509_CRL *crl, X509 *x);
132static int get_crl_delta(X509_STORE_CTX *ctx,
133 X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
134static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
135 X509_CRL *base, STACK_OF(X509_CRL) *crls);
136static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
137 int *pcrl_score);
138static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
139 unsigned int *preasons);
140static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
141static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path,
142 STACK_OF(X509) *crl_path);
143static int X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time,
144 int clamp_notafter);
145
146static int internal_verify(X509_STORE_CTX *ctx);
147static int check_key_level(X509_STORE_CTX *ctx, X509 *cert);
148static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err);
149
150static int
151null_callback(int ok, X509_STORE_CTX *e)
152{
153 return ok;
154}
155
156/* Return 1 if a certificate is self signed */
157static int
158cert_self_signed(X509 *x)
159{
160 X509_check_purpose(x, -1, 0);
161 if (x->ex_flags & EXFLAG_SS)
162 return 1;
163 else
164 return 0;
165}
166
167static int
168check_id_error(X509_STORE_CTX *ctx, int errcode)
169{
170 ctx->error = errcode;
171 ctx->current_cert = ctx->cert;
172 ctx->error_depth = 0;
173 return ctx->verify_cb(0, ctx);
174}
175
176static int
177x509_vfy_check_hosts(X509 *x, X509_VERIFY_PARAM *vpm)
178{
179 int i, n;
180 char *name;
181
182 n = sk_OPENSSL_STRING_num(vpm->hosts);
183 free(vpm->peername);
184 vpm->peername = NULL;
185
186 for (i = 0; i < n; ++i) {
187 name = sk_OPENSSL_STRING_value(vpm->hosts, i);
188 if (X509_check_host(x, name, strlen(name), vpm->hostflags,
189 &vpm->peername) > 0)
190 return 1;
191 }
192 return n == 0;
193}
194
195int
196x509_vfy_check_id(X509_STORE_CTX *ctx)
197{
198 X509_VERIFY_PARAM *vpm = ctx->param;
199 X509 *x = ctx->cert;
200
201 if (vpm->hosts && x509_vfy_check_hosts(x, vpm) <= 0) {
202 if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
203 return 0;
204 }
205 if (vpm->email != NULL && X509_check_email(x, vpm->email, vpm->emaillen, 0)
206 <= 0) {
207 if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
208 return 0;
209 }
210 if (vpm->ip != NULL && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) {
211 if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
212 return 0;
213 }
214 return 1;
215}
216
217/*
218 * This is the effectively broken legacy OpenSSL chain builder. It
219 * might find an unvalidated chain and leave it sitting in
220 * ctx->chain. It does not correctly handle many cases where multiple
221 * chains could exist.
222 *
223 * Oh no.. I know a dirty word...
224 * Oooooooh..
225 */
226static int
227X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad, int *out_ok)
228{
229 X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
230 int bad_chain = 0;
231 X509_VERIFY_PARAM *param = ctx->param;
232 int ok = 0, ret = 0;
233 int depth, i;
234 int num, j, retry, trust;
235 int (*cb) (int xok, X509_STORE_CTX *xctx);
236 STACK_OF(X509) *sktmp = NULL;
237
238 cb = ctx->verify_cb;
239
240 /*
241 * First we make sure the chain we are going to build is
242 * present and that the first entry is in place.
243 */
244 ctx->chain = sk_X509_new_null();
245 if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) {
246 X509error(ERR_R_MALLOC_FAILURE);
247 ctx->error = X509_V_ERR_OUT_OF_MEM;
248 goto end;
249 }
250 X509_up_ref(ctx->cert);
251 ctx->num_untrusted = 1;
252
253 /* We use a temporary STACK so we can chop and hack at it */
254 if (ctx->untrusted != NULL &&
255 (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
256 X509error(ERR_R_MALLOC_FAILURE);
257 ctx->error = X509_V_ERR_OUT_OF_MEM;
258 goto end;
259 }
260
261 num = sk_X509_num(ctx->chain);
262 x = sk_X509_value(ctx->chain, num - 1);
263 depth = param->depth;
264
265 for (;;) {
266 /* If we have enough, we break */
267 /* FIXME: If this happens, we should take
268 * note of it and, if appropriate, use the
269 * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
270 * later.
271 */
272 if (depth < num)
273 break;
274 /* If we are self signed, we break */
275 if (cert_self_signed(x))
276 break;
277 /*
278 * If asked see if we can find issuer in trusted store first
279 */
280 if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
281 ok = ctx->get_issuer(&xtmp, ctx, x);
282 if (ok < 0) {
283 ctx->error = X509_V_ERR_STORE_LOOKUP;
284 goto end;
285 }
286 /*
287 * If successful for now free up cert so it
288 * will be picked up again later.
289 */
290 if (ok > 0) {
291 X509_free(xtmp);
292 break;
293 }
294 }
295 /* If we were passed a cert chain, use it first */
296 if (ctx->untrusted != NULL) {
297 /*
298 * If we do not find a non-expired untrusted cert, peek
299 * ahead and see if we can satisfy this from the trusted
300 * store. If not, see if we have an expired untrusted cert.
301 */
302 xtmp = find_issuer(ctx, sktmp, x, 0);
303 if (xtmp == NULL &&
304 !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)) {
305 ok = ctx->get_issuer(&xtmp, ctx, x);
306 if (ok < 0) {
307 ctx->error = X509_V_ERR_STORE_LOOKUP;
308 goto end;
309 }
310 if (ok > 0) {
311 X509_free(xtmp);
312 break;
313 }
314 xtmp = find_issuer(ctx, sktmp, x, 1);
315 }
316 if (xtmp != NULL) {
317 if (!sk_X509_push(ctx->chain, xtmp)) {
318 X509error(ERR_R_MALLOC_FAILURE);
319 ctx->error = X509_V_ERR_OUT_OF_MEM;
320 ok = 0;
321 goto end;
322 }
323 X509_up_ref(xtmp);
324 (void)sk_X509_delete_ptr(sktmp, xtmp);
325 ctx->num_untrusted++;
326 x = xtmp;
327 num++;
328 /*
329 * reparse the full chain for the next one
330 */
331 continue;
332 }
333 }
334 break;
335 }
336 /* Remember how many untrusted certs we have */
337 j = num;
338
339 /*
340 * At this point, chain should contain a list of untrusted
341 * certificates. We now need to add at least one trusted one,
342 * if possible, otherwise we complain.
343 */
344
345 do {
346 /*
347 * Examine last certificate in chain and see if it is
348 * self signed.
349 */
350 i = sk_X509_num(ctx->chain);
351 x = sk_X509_value(ctx->chain, i - 1);
352 if (cert_self_signed(x)) {
353 /* we have a self signed certificate */
354 if (i == 1) {
355 /*
356 * We have a single self signed
357 * certificate: see if we can find it
358 * in the store. We must have an exact
359 * match to avoid possible
360 * impersonation.
361 */
362 ok = ctx->get_issuer(&xtmp, ctx, x);
363 if ((ok <= 0) || X509_cmp(x, xtmp)) {
364 ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
365 ctx->current_cert = x;
366 ctx->error_depth = i - 1;
367 if (ok == 1)
368 X509_free(xtmp);
369 bad_chain = 1;
370 ok = cb(0, ctx);
371 if (!ok)
372 goto end;
373 } else {
374 /*
375 * We have a match: replace
376 * certificate with store
377 * version so we get any trust
378 * settings.
379 */
380 X509_free(x);
381 x = xtmp;
382 (void)sk_X509_set(ctx->chain, i - 1, x);
383 ctx->num_untrusted = 0;
384 }
385 } else {
386 /*
387 * extract and save self signed
388 * certificate for later use
389 */
390 chain_ss = sk_X509_pop(ctx->chain);
391 ctx->num_untrusted--;
392 num--;
393 j--;
394 x = sk_X509_value(ctx->chain, num - 1);
395 }
396 }
397 /* We now lookup certs from the certificate store */
398 for (;;) {
399 /* If we have enough, we break */
400 if (depth < num)
401 break;
402 /* If we are self signed, we break */
403 if (cert_self_signed(x))
404 break;
405 ok = ctx->get_issuer(&xtmp, ctx, x);
406
407 if (ok < 0) {
408 ctx->error = X509_V_ERR_STORE_LOOKUP;
409 goto end;
410 }
411 if (ok == 0)
412 break;
413 x = xtmp;
414 if (!sk_X509_push(ctx->chain, x)) {
415 X509_free(xtmp);
416 X509error(ERR_R_MALLOC_FAILURE);
417 ctx->error = X509_V_ERR_OUT_OF_MEM;
418 ok = 0;
419 goto end;
420 }
421 num++;
422 }
423
424 /* we now have our chain, lets check it... */
425 trust = x509_vfy_check_trust(ctx);
426
427 /* If explicitly rejected error */
428 if (trust == X509_TRUST_REJECTED) {
429 ok = 0;
430 goto end;
431 }
432 /*
433 * If it's not explicitly trusted then check if there
434 * is an alternative chain that could be used. We only
435 * do this if we haven't already checked via
436 * TRUSTED_FIRST and the user hasn't switched off
437 * alternate chain checking
438 */
439 retry = 0;
440 if (trust != X509_TRUST_TRUSTED &&
441 !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) &&
442 !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
443 while (j-- > 1) {
444 xtmp2 = sk_X509_value(ctx->chain, j - 1);
445 ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
446 if (ok < 0)
447 goto end;
448 /* Check if we found an alternate chain */
449 if (ok > 0) {
450 /*
451 * Free up the found cert
452 * we'll add it again later
453 */
454 X509_free(xtmp);
455 /*
456 * Dump all the certs above
457 * this point - we've found an
458 * alternate chain
459 */
460 while (num > j) {
461 xtmp = sk_X509_pop(ctx->chain);
462 X509_free(xtmp);
463 num--;
464 }
465 ctx->num_untrusted = sk_X509_num(ctx->chain);
466 retry = 1;
467 break;
468 }
469 }
470 }
471 } while (retry);
472
473 /*
474 * If not explicitly trusted then indicate error unless it's a single
475 * self signed certificate in which case we've indicated an error already
476 * and set bad_chain == 1
477 */
478 if (trust != X509_TRUST_TRUSTED && !bad_chain) {
479 if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
480 if (ctx->num_untrusted >= num)
481 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
482 else
483 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
484 ctx->current_cert = x;
485 } else {
486 if (!sk_X509_push(ctx->chain, chain_ss)) {
487 X509error(ERR_R_MALLOC_FAILURE);
488 ctx->error = X509_V_ERR_OUT_OF_MEM;
489 ok = 0;
490 goto end;
491 }
492 num++;
493 ctx->num_untrusted = num;
494 ctx->current_cert = chain_ss;
495 ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
496 chain_ss = NULL;
497 }
498
499 ctx->error_depth = num - 1;
500 bad_chain = 1;
501 ok = cb(0, ctx);
502 if (!ok)
503 goto end;
504 }
505
506 ret = 1;
507 end:
508 sk_X509_free(sktmp);
509 X509_free(chain_ss);
510 *bad = bad_chain;
511 *out_ok = ok;
512
513 return ret;
514}
515
516static int
517X509_verify_cert_legacy(X509_STORE_CTX *ctx)
518{
519 int ok = 0, bad_chain;
520
521 ctx->error = X509_V_OK; /* Initialize to OK */
522
523 if (!X509_verify_cert_legacy_build_chain(ctx, &bad_chain, &ok))
524 goto end;
525
526 /* We have the chain complete: now we need to check its purpose */
527 ok = x509_vfy_check_chain_extensions(ctx);
528 if (!ok)
529 goto end;
530
531 /* Check that the chain satisfies the security level. */
532 ok = x509_vfy_check_security_level(ctx);
533 if (!ok)
534 goto end;
535
536 /* Check name constraints */
537 ok = check_name_constraints(ctx);
538 if (!ok)
539 goto end;
540
541#ifndef OPENSSL_NO_RFC3779
542 ok = X509v3_asid_validate_path(ctx);
543 if (!ok)
544 goto end;
545
546 ok = X509v3_addr_validate_path(ctx);
547 if (!ok)
548 goto end;
549#endif
550
551 ok = x509_vfy_check_id(ctx);
552 if (!ok)
553 goto end;
554
555 /*
556 * Check revocation status: we do this after copying parameters because
557 * they may be needed for CRL signature verification.
558 */
559 ok = x509_vfy_check_revocation(ctx);
560 if (!ok)
561 goto end;
562
563 /* At this point, we have a chain and need to verify it */
564 if (ctx->verify != NULL)
565 ok = ctx->verify(ctx);
566 else
567 ok = internal_verify(ctx);
568 if (!ok)
569 goto end;
570
571 /* If we get this far evaluate policies */
572 if (!bad_chain)
573 ok = x509_vfy_check_policy(ctx);
574
575 end:
576 /* Safety net, error returns must set ctx->error */
577 if (ok <= 0 && ctx->error == X509_V_OK)
578 ctx->error = X509_V_ERR_UNSPECIFIED;
579
580 return ok;
581}
582
583int
584X509_verify_cert(X509_STORE_CTX *ctx)
585{
586 struct x509_verify_ctx *vctx = NULL;
587 int chain_count = 0;
588
589 if (ctx->cert == NULL) {
590 X509error(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
591 ctx->error = X509_V_ERR_INVALID_CALL;
592 return -1;
593 }
594 if (ctx->chain != NULL) {
595 /*
596 * This X509_STORE_CTX has already been used to verify
597 * a cert. We cannot do another one.
598 */
599 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
600 ctx->error = X509_V_ERR_INVALID_CALL;
601 return -1;
602 }
603 if (ctx->param->poisoned) {
604 /*
605 * This X509_STORE_CTX had failures setting
606 * up verify parameters. We can not use it.
607 */
608 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
609 ctx->error = X509_V_ERR_INVALID_CALL;
610 return -1;
611 }
612 if (ctx->error != X509_V_ERR_INVALID_CALL) {
613 /*
614 * This X509_STORE_CTX has not been properly initialized.
615 */
616 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
617 ctx->error = X509_V_ERR_INVALID_CALL;
618 return -1;
619 }
620
621 /*
622 * If the certificate's public key is too weak, don't bother
623 * continuing.
624 */
625 if (!check_key_level(ctx, ctx->cert) &&
626 !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL))
627 return 0;
628
629 /*
630 * If flags request legacy, use the legacy verifier. If we
631 * requested "no alt chains" from the age of hammer pants, use
632 * the legacy verifier because the multi chain verifier really
633 * does find all the "alt chains".
634 *
635 * XXX deprecate the NO_ALT_CHAINS flag?
636 */
637 if ((ctx->param->flags & X509_V_FLAG_LEGACY_VERIFY) ||
638 (ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS))
639 return X509_verify_cert_legacy(ctx);
640
641 /* Use the modern multi-chain verifier from x509_verify_cert */
642
643 if ((vctx = x509_verify_ctx_new_from_xsc(ctx)) != NULL) {
644 ctx->error = X509_V_OK; /* Initialize to OK */
645 chain_count = x509_verify(vctx, NULL, NULL);
646 }
647 x509_verify_ctx_free(vctx);
648
649 /* if we succeed we have a chain in ctx->chain */
650 return chain_count > 0 && ctx->chain != NULL;
651}
652LCRYPTO_ALIAS(X509_verify_cert);
653
654/* Given a STACK_OF(X509) find the issuer of cert (if any)
655 */
656
657static X509 *
658find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x,
659 int allow_expired)
660{
661 int i;
662 X509 *issuer, *rv = NULL;
663
664 for (i = 0; i < sk_X509_num(sk); i++) {
665 issuer = sk_X509_value(sk, i);
666 if (ctx->check_issued(ctx, x, issuer)) {
667 if (x509_check_cert_time(ctx, issuer, -1))
668 return issuer;
669 if (allow_expired)
670 rv = issuer;
671 }
672 }
673 return rv;
674}
675
676/* Given a possible certificate and issuer check them */
677
678static int
679check_issued(X509_STORE_CTX *ctx, X509 *subject, X509 *issuer)
680{
681 /*
682 * Yes, the arguments of X509_STORE_CTX_check_issued_fn were exposed in
683 * reverse order compared to the already public X509_check_issued()...
684 */
685 return X509_check_issued(issuer, subject) == X509_V_OK;
686}
687
688/* Alternative lookup method: look from a STACK stored in ctx->trusted */
689
690static int
691x509_vfy_get_trusted_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
692{
693 *issuer = find_issuer(ctx, ctx->trusted, x, 1);
694 if (*issuer) {
695 CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
696 return 1;
697 } else
698 return 0;
699}
700
701/* Check a certificate chains extensions for consistency
702 * with the supplied purpose
703 */
704
705int
706x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx)
707{
708 int i, ok = 0, must_be_ca, plen = 0;
709 X509 *x;
710 int (*cb)(int xok, X509_STORE_CTX *xctx);
711 int proxy_path_length = 0;
712 int purpose;
713
714 cb = ctx->verify_cb;
715
716 /* must_be_ca can have 1 of 3 values:
717 -1: we accept both CA and non-CA certificates, to allow direct
718 use of self-signed certificates (which are marked as CA).
719 0: we only accept non-CA certificates. This is currently not
720 used, but the possibility is present for future extensions.
721 1: we only accept CA certificates. This is currently used for
722 all certificates in the chain except the leaf certificate.
723 */
724 must_be_ca = -1;
725
726 /* CRL path validation */
727 if (ctx->parent)
728 purpose = X509_PURPOSE_CRL_SIGN;
729 else
730 purpose = ctx->param->purpose;
731
732 /* Check all untrusted certificates */
733 for (i = 0; i < ctx->num_untrusted; i++) {
734 int ret;
735 x = sk_X509_value(ctx->chain, i);
736 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) &&
737 (x->ex_flags & EXFLAG_CRITICAL)) {
738 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
739 ctx->error_depth = i;
740 ctx->current_cert = x;
741 ok = cb(0, ctx);
742 if (!ok)
743 goto end;
744 }
745 ret = X509_check_ca(x);
746 if (must_be_ca == -1) {
747 if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) &&
748 (ret != 1) && (ret != 0)) {
749 ret = 0;
750 ctx->error = X509_V_ERR_INVALID_CA;
751 } else
752 ret = 1;
753 } else {
754 if ((ret == 0) ||
755 ((ctx->param->flags & X509_V_FLAG_X509_STRICT) &&
756 (ret != 1))) {
757 ret = 0;
758 ctx->error = X509_V_ERR_INVALID_CA;
759 } else
760 ret = 1;
761 }
762 if (ret == 0) {
763 ctx->error_depth = i;
764 ctx->current_cert = x;
765 ok = cb(0, ctx);
766 if (!ok)
767 goto end;
768 }
769 if (ctx->param->purpose > 0) {
770 ret = X509_check_purpose(x, purpose, must_be_ca > 0);
771 if ((ret == 0) ||
772 ((ctx->param->flags & X509_V_FLAG_X509_STRICT) &&
773 (ret != 1))) {
774 ctx->error = X509_V_ERR_INVALID_PURPOSE;
775 ctx->error_depth = i;
776 ctx->current_cert = x;
777 ok = cb(0, ctx);
778 if (!ok)
779 goto end;
780 }
781 }
782 /* Check pathlen if not self issued */
783 if ((i > 1) && !(x->ex_flags & EXFLAG_SI) &&
784 (x->ex_pathlen != -1) &&
785 (plen > (x->ex_pathlen + proxy_path_length + 1))) {
786 ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
787 ctx->error_depth = i;
788 ctx->current_cert = x;
789 ok = cb(0, ctx);
790 if (!ok)
791 goto end;
792 }
793 /* Increment path length if not self issued */
794 if (!(x->ex_flags & EXFLAG_SI))
795 plen++;
796 must_be_ca = 1;
797 }
798
799 ok = 1;
800
801 end:
802 return ok;
803}
804
805static int
806check_name_constraints(X509_STORE_CTX *ctx)
807{
808 if (!x509_constraints_chain(ctx->chain, &ctx->error,
809 &ctx->error_depth)) {
810 ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
811 if (!ctx->verify_cb(0, ctx))
812 return 0;
813 }
814 return 1;
815}
816
817/* Given a certificate try and find an exact match in the store */
818
819static X509 *
820lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
821{
822 STACK_OF(X509) *certs;
823 X509 *xtmp = NULL;
824 size_t i;
825
826 /* Lookup all certs with matching subject name */
827 certs = X509_STORE_CTX_get1_certs(ctx, X509_get_subject_name(x));
828 if (certs == NULL)
829 return NULL;
830
831 /* Look for exact match */
832 for (i = 0; i < sk_X509_num(certs); i++) {
833 xtmp = sk_X509_value(certs, i);
834 if (!X509_cmp(xtmp, x))
835 break;
836 }
837
838 if (i < sk_X509_num(certs))
839 X509_up_ref(xtmp);
840 else
841 xtmp = NULL;
842
843 sk_X509_pop_free(certs, X509_free);
844 return xtmp;
845}
846
847X509 *
848x509_vfy_lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
849{
850 if (ctx->store == NULL || ctx->store->objs == NULL)
851 return NULL;
852 return lookup_cert_match(ctx, x);
853}
854
855int
856x509_vfy_check_trust(X509_STORE_CTX *ctx)
857{
858 size_t i;
859 int ok;
860 X509 *x = NULL;
861 int (*cb) (int xok, X509_STORE_CTX *xctx);
862
863 cb = ctx->verify_cb;
864 /* Check all trusted certificates in chain */
865 for (i = ctx->num_untrusted; i < sk_X509_num(ctx->chain); i++) {
866 x = sk_X509_value(ctx->chain, i);
867 ok = X509_check_trust(x, ctx->param->trust, 0);
868
869 /* If explicitly trusted return trusted */
870 if (ok == X509_TRUST_TRUSTED)
871 return X509_TRUST_TRUSTED;
872 /*
873 * If explicitly rejected notify callback and reject if not
874 * overridden.
875 */
876 if (ok == X509_TRUST_REJECTED) {
877 ctx->error_depth = i;
878 ctx->current_cert = x;
879 ctx->error = X509_V_ERR_CERT_REJECTED;
880 ok = cb(0, ctx);
881 if (!ok)
882 return X509_TRUST_REJECTED;
883 }
884 }
885 /*
886 * If we accept partial chains and have at least one trusted certificate
887 * return success.
888 */
889 if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
890 X509 *mx;
891 if (ctx->num_untrusted < (int)sk_X509_num(ctx->chain))
892 return X509_TRUST_TRUSTED;
893 x = sk_X509_value(ctx->chain, 0);
894 mx = lookup_cert_match(ctx, x);
895 if (mx) {
896 (void)sk_X509_set(ctx->chain, 0, mx);
897 X509_free(x);
898 ctx->num_untrusted = 0;
899 return X509_TRUST_TRUSTED;
900 }
901 }
902
903 /*
904 * If no trusted certs in chain at all return untrusted and allow
905 * standard (no issuer cert) etc errors to be indicated.
906 */
907 return X509_TRUST_UNTRUSTED;
908}
909
910int
911x509_vfy_check_revocation(X509_STORE_CTX *ctx)
912{
913 int i, last, ok;
914
915 if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
916 return 1;
917 if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
918 last = sk_X509_num(ctx->chain) - 1;
919 else {
920 /* If checking CRL paths this isn't the EE certificate */
921 if (ctx->parent)
922 return 1;
923 last = 0;
924 }
925 for (i = 0; i <= last; i++) {
926 ok = check_cert(ctx, ctx->chain, i);
927 if (!ok)
928 return ok;
929 }
930 return 1;
931}
932
933static int
934check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth)
935{
936 X509_CRL *crl = NULL, *dcrl = NULL;
937 X509 *x;
938 int ok = 0, cnum;
939 unsigned int last_reasons;
940
941 cnum = ctx->error_depth = depth;
942 x = sk_X509_value(chain, cnum);
943 ctx->current_cert = x;
944 ctx->current_issuer = NULL;
945 ctx->current_crl_score = 0;
946 ctx->current_reasons = 0;
947 while (ctx->current_reasons != CRLDP_ALL_REASONS) {
948 last_reasons = ctx->current_reasons;
949 /* Try to retrieve relevant CRL */
950 ok = get_crl_delta(ctx, &crl, &dcrl, x);
951 if (!ok) {
952 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
953 ok = ctx->verify_cb(0, ctx);
954 goto err;
955 }
956 ctx->current_crl = crl;
957 ok = x509_vfy_check_crl(ctx, crl);
958 if (!ok)
959 goto err;
960
961 if (dcrl) {
962 ok = x509_vfy_check_crl(ctx, dcrl);
963 if (!ok)
964 goto err;
965 ok = x509_vfy_cert_crl(ctx, dcrl, x);
966 if (!ok)
967 goto err;
968 } else
969 ok = 1;
970
971 /* Don't look in full CRL if delta reason is removefromCRL */
972 if (ok != 2) {
973 ok = x509_vfy_cert_crl(ctx, crl, x);
974 if (!ok)
975 goto err;
976 }
977
978 ctx->current_crl = NULL;
979 X509_CRL_free(crl);
980 X509_CRL_free(dcrl);
981 crl = NULL;
982 dcrl = NULL;
983 /* If reasons not updated we wont get anywhere by
984 * another iteration, so exit loop.
985 */
986 if (last_reasons == ctx->current_reasons) {
987 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
988 ok = ctx->verify_cb(0, ctx);
989 goto err;
990 }
991 }
992
993err:
994 ctx->current_crl = NULL;
995 X509_CRL_free(crl);
996 X509_CRL_free(dcrl);
997 return ok;
998}
999
1000/* Check CRL times against values in X509_STORE_CTX */
1001
1002static int
1003check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
1004{
1005 time_t *ptime;
1006 int i;
1007
1008 if (notify)
1009 ctx->current_crl = crl;
1010 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
1011 ptime = &ctx->param->check_time;
1012 else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
1013 return 1;
1014 else
1015 ptime = NULL;
1016
1017 i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
1018 if (i == 0) {
1019 if (!notify)
1020 return 0;
1021 ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
1022 if (!ctx->verify_cb(0, ctx))
1023 return 0;
1024 }
1025
1026 if (i > 0) {
1027 if (!notify)
1028 return 0;
1029 ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
1030 if (!ctx->verify_cb(0, ctx))
1031 return 0;
1032 }
1033
1034 if (X509_CRL_get_nextUpdate(crl)) {
1035 i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
1036
1037 if (i == 0) {
1038 if (!notify)
1039 return 0;
1040 ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
1041 if (!ctx->verify_cb(0, ctx))
1042 return 0;
1043 }
1044 /* Ignore expiry of base CRL is delta is valid */
1045 if ((i < 0) &&
1046 !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
1047 if (!notify)
1048 return 0;
1049 ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
1050 if (!ctx->verify_cb(0, ctx))
1051 return 0;
1052 }
1053 }
1054
1055 if (notify)
1056 ctx->current_crl = NULL;
1057
1058 return 1;
1059}
1060
1061static int
1062get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
1063 X509 **pissuer, int *pscore, unsigned int *preasons,
1064 STACK_OF(X509_CRL) *crls)
1065{
1066 int i, crl_score, best_score = *pscore;
1067 unsigned int reasons, best_reasons = 0;
1068 X509 *x = ctx->current_cert;
1069 X509_CRL *crl, *best_crl = NULL;
1070 X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
1071
1072 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
1073 crl = sk_X509_CRL_value(crls, i);
1074 reasons = *preasons;
1075 crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
1076
1077 if (crl_score > best_score) {
1078 best_crl = crl;
1079 best_crl_issuer = crl_issuer;
1080 best_score = crl_score;
1081 best_reasons = reasons;
1082 }
1083 }
1084
1085 if (best_crl) {
1086 if (*pcrl)
1087 X509_CRL_free(*pcrl);
1088 *pcrl = best_crl;
1089 *pissuer = best_crl_issuer;
1090 *pscore = best_score;
1091 *preasons = best_reasons;
1092 CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
1093 if (*pdcrl) {
1094 X509_CRL_free(*pdcrl);
1095 *pdcrl = NULL;
1096 }
1097 get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
1098 }
1099
1100 if (best_score >= CRL_SCORE_VALID)
1101 return 1;
1102
1103 return 0;
1104}
1105
1106/* Compare two CRL extensions for delta checking purposes. They should be
1107 * both present or both absent. If both present all fields must be identical.
1108 */
1109
1110static int
1111crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
1112{
1113 ASN1_OCTET_STRING *exta, *extb;
1114 int i;
1115
1116 i = X509_CRL_get_ext_by_NID(a, nid, -1);
1117 if (i >= 0) {
1118 /* Can't have multiple occurrences */
1119 if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
1120 return 0;
1121 exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
1122 } else
1123 exta = NULL;
1124
1125 i = X509_CRL_get_ext_by_NID(b, nid, -1);
1126
1127 if (i >= 0) {
1128 if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
1129 return 0;
1130 extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
1131 } else
1132 extb = NULL;
1133
1134 if (!exta && !extb)
1135 return 1;
1136
1137 if (!exta || !extb)
1138 return 0;
1139
1140 if (ASN1_OCTET_STRING_cmp(exta, extb))
1141 return 0;
1142
1143 return 1;
1144}
1145
1146/* See if a base and delta are compatible */
1147
1148static int
1149check_delta_base(X509_CRL *delta, X509_CRL *base)
1150{
1151 /* Delta CRL must be a delta */
1152 if (!delta->base_crl_number)
1153 return 0;
1154 /* Base must have a CRL number */
1155 if (!base->crl_number)
1156 return 0;
1157 /* Issuer names must match */
1158 if (X509_NAME_cmp(X509_CRL_get_issuer(base),
1159 X509_CRL_get_issuer(delta)))
1160 return 0;
1161 /* AKID and IDP must match */
1162 if (!crl_extension_match(delta, base, NID_authority_key_identifier))
1163 return 0;
1164 if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
1165 return 0;
1166 /* Delta CRL base number must not exceed Full CRL number. */
1167 if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
1168 return 0;
1169 /* Delta CRL number must exceed full CRL number */
1170 if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
1171 return 1;
1172 return 0;
1173}
1174
1175/* For a given base CRL find a delta... maybe extend to delta scoring
1176 * or retrieve a chain of deltas...
1177 */
1178
1179static void
1180get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, X509_CRL *base,
1181 STACK_OF(X509_CRL) *crls)
1182{
1183 X509_CRL *delta;
1184 int i;
1185
1186 if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
1187 return;
1188 if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
1189 return;
1190 for (i = 0; i < sk_X509_CRL_num(crls); i++) {
1191 delta = sk_X509_CRL_value(crls, i);
1192 if (check_delta_base(delta, base)) {
1193 if (check_crl_time(ctx, delta, 0))
1194 *pscore |= CRL_SCORE_TIME_DELTA;
1195 CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
1196 *dcrl = delta;
1197 return;
1198 }
1199 }
1200 *dcrl = NULL;
1201}
1202
1203/* For a given CRL return how suitable it is for the supplied certificate 'x'.
1204 * The return value is a mask of several criteria.
1205 * If the issuer is not the certificate issuer this is returned in *pissuer.
1206 * The reasons mask is also used to determine if the CRL is suitable: if
1207 * no new reasons the CRL is rejected, otherwise reasons is updated.
1208 */
1209
1210static int
1211get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons,
1212 X509_CRL *crl, X509 *x)
1213{
1214 int crl_score = 0;
1215 unsigned int tmp_reasons = *preasons, crl_reasons;
1216
1217 /* First see if we can reject CRL straight away */
1218
1219 /* Invalid IDP cannot be processed */
1220 if (crl->idp_flags & IDP_INVALID)
1221 return 0;
1222 /* Reason codes or indirect CRLs need extended CRL support */
1223 if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
1224 if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
1225 return 0;
1226 } else if (crl->idp_flags & IDP_REASONS) {
1227 /* If no new reasons reject */
1228 if (!(crl->idp_reasons & ~tmp_reasons))
1229 return 0;
1230 }
1231 /* Don't process deltas at this stage */
1232 else if (crl->base_crl_number)
1233 return 0;
1234 /* If issuer name doesn't match certificate need indirect CRL */
1235 if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
1236 if (!(crl->idp_flags & IDP_INDIRECT))
1237 return 0;
1238 } else
1239 crl_score |= CRL_SCORE_ISSUER_NAME;
1240
1241 if (!(crl->flags & EXFLAG_CRITICAL))
1242 crl_score |= CRL_SCORE_NOCRITICAL;
1243
1244 /* Check expiry */
1245 if (check_crl_time(ctx, crl, 0))
1246 crl_score |= CRL_SCORE_TIME;
1247
1248 /* Check authority key ID and locate certificate issuer */
1249 crl_akid_check(ctx, crl, pissuer, &crl_score);
1250
1251 /* If we can't locate certificate issuer at this point forget it */
1252
1253 if (!(crl_score & CRL_SCORE_AKID))
1254 return 0;
1255
1256 /* Check cert for matching CRL distribution points */
1257
1258 if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
1259 /* If no new reasons reject */
1260 if (!(crl_reasons & ~tmp_reasons))
1261 return 0;
1262 tmp_reasons |= crl_reasons;
1263 crl_score |= CRL_SCORE_SCOPE;
1264 }
1265
1266 *preasons = tmp_reasons;
1267
1268 return crl_score;
1269}
1270
1271static void
1272crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
1273 int *pcrl_score)
1274{
1275 X509 *crl_issuer = NULL;
1276 X509_NAME *cnm = X509_CRL_get_issuer(crl);
1277 int cidx = ctx->error_depth;
1278 int i;
1279
1280 if (cidx != sk_X509_num(ctx->chain) - 1)
1281 cidx++;
1282
1283 crl_issuer = sk_X509_value(ctx->chain, cidx);
1284
1285 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1286 if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
1287 *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
1288 *pissuer = crl_issuer;
1289 return;
1290 }
1291 }
1292
1293 for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) {
1294 crl_issuer = sk_X509_value(ctx->chain, cidx);
1295 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1296 continue;
1297 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1298 *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
1299 *pissuer = crl_issuer;
1300 return;
1301 }
1302 }
1303
1304 /* Anything else needs extended CRL support */
1305
1306 if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
1307 return;
1308
1309 /* Otherwise the CRL issuer is not on the path. Look for it in the
1310 * set of untrusted certificates.
1311 */
1312 for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
1313 crl_issuer = sk_X509_value(ctx->untrusted, i);
1314 if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1315 continue;
1316 if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1317 *pissuer = crl_issuer;
1318 *pcrl_score |= CRL_SCORE_AKID;
1319 return;
1320 }
1321 }
1322}
1323
1324/* Check the path of a CRL issuer certificate. This creates a new
1325 * X509_STORE_CTX and populates it with most of the parameters from the
1326 * parent. This could be optimised somewhat since a lot of path checking
1327 * will be duplicated by the parent, but this will rarely be used in
1328 * practice.
1329 */
1330
1331static int
1332check_crl_path(X509_STORE_CTX *ctx, X509 *x)
1333{
1334 X509_STORE_CTX crl_ctx;
1335 int ret;
1336
1337 /* Don't allow recursive CRL path validation */
1338 if (ctx->parent)
1339 return 0;
1340 if (!X509_STORE_CTX_init(&crl_ctx, ctx->store, x, ctx->untrusted)) {
1341 ret = -1;
1342 goto err;
1343 }
1344
1345 crl_ctx.crls = ctx->crls;
1346 /* Copy verify params across */
1347 X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
1348
1349 crl_ctx.parent = ctx;
1350 crl_ctx.verify_cb = ctx->verify_cb;
1351
1352 /* Verify CRL issuer */
1353 ret = X509_verify_cert(&crl_ctx);
1354
1355 if (ret <= 0)
1356 goto err;
1357
1358 /* Check chain is acceptable */
1359 ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
1360
1361err:
1362 X509_STORE_CTX_cleanup(&crl_ctx);
1363 return ret;
1364}
1365
1366/* RFC3280 says nothing about the relationship between CRL path
1367 * and certificate path, which could lead to situations where a
1368 * certificate could be revoked or validated by a CA not authorised
1369 * to do so. RFC5280 is more strict and states that the two paths must
1370 * end in the same trust anchor, though some discussions remain...
1371 * until this is resolved we use the RFC5280 version
1372 */
1373
1374static int
1375check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path,
1376 STACK_OF(X509) *crl_path)
1377{
1378 X509 *cert_ta, *crl_ta;
1379
1380 cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
1381 crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
1382 if (!X509_cmp(cert_ta, crl_ta))
1383 return 1;
1384 return 0;
1385}
1386
1387/* Check for match between two dist point names: three separate cases.
1388 * 1. Both are relative names and compare X509_NAME types.
1389 * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
1390 * 3. Both are full names and compare two GENERAL_NAMES.
1391 * 4. One is NULL: automatic match.
1392 */
1393
1394static int
1395idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
1396{
1397 X509_NAME *nm = NULL;
1398 GENERAL_NAMES *gens = NULL;
1399 GENERAL_NAME *gena, *genb;
1400 int i, j;
1401
1402 if (!a || !b)
1403 return 1;
1404 if (a->type == 1) {
1405 if (!a->dpname)
1406 return 0;
1407 /* Case 1: two X509_NAME */
1408 if (b->type == 1) {
1409 if (!b->dpname)
1410 return 0;
1411 if (!X509_NAME_cmp(a->dpname, b->dpname))
1412 return 1;
1413 else
1414 return 0;
1415 }
1416 /* Case 2: set name and GENERAL_NAMES appropriately */
1417 nm = a->dpname;
1418 gens = b->name.fullname;
1419 } else if (b->type == 1) {
1420 if (!b->dpname)
1421 return 0;
1422 /* Case 2: set name and GENERAL_NAMES appropriately */
1423 gens = a->name.fullname;
1424 nm = b->dpname;
1425 }
1426
1427 /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
1428 if (nm) {
1429 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1430 gena = sk_GENERAL_NAME_value(gens, i);
1431 if (gena->type != GEN_DIRNAME)
1432 continue;
1433 if (!X509_NAME_cmp(nm, gena->d.directoryName))
1434 return 1;
1435 }
1436 return 0;
1437 }
1438
1439 /* Else case 3: two GENERAL_NAMES */
1440
1441 for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
1442 gena = sk_GENERAL_NAME_value(a->name.fullname, i);
1443 for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
1444 genb = sk_GENERAL_NAME_value(b->name.fullname, j);
1445 if (!GENERAL_NAME_cmp(gena, genb))
1446 return 1;
1447 }
1448 }
1449
1450 return 0;
1451}
1452
1453static int
1454crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
1455{
1456 int i;
1457 X509_NAME *nm = X509_CRL_get_issuer(crl);
1458
1459 /* If no CRLissuer return is successful iff don't need a match */
1460 if (!dp->CRLissuer)
1461 return !!(crl_score & CRL_SCORE_ISSUER_NAME);
1462 for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
1463 GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
1464 if (gen->type != GEN_DIRNAME)
1465 continue;
1466 if (!X509_NAME_cmp(gen->d.directoryName, nm))
1467 return 1;
1468 }
1469 return 0;
1470}
1471
1472/* Check CRLDP and IDP */
1473
1474static int
1475crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, unsigned int *preasons)
1476{
1477 int i;
1478
1479 if (crl->idp_flags & IDP_ONLYATTR)
1480 return 0;
1481 if (x->ex_flags & EXFLAG_CA) {
1482 if (crl->idp_flags & IDP_ONLYUSER)
1483 return 0;
1484 } else {
1485 if (crl->idp_flags & IDP_ONLYCA)
1486 return 0;
1487 }
1488 *preasons = crl->idp_reasons;
1489 for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
1490 DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
1491 if (crldp_check_crlissuer(dp, crl, crl_score)) {
1492 if (!crl->idp ||
1493 idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
1494 *preasons &= dp->dp_reasons;
1495 return 1;
1496 }
1497 }
1498 }
1499 if ((!crl->idp || !crl->idp->distpoint) &&
1500 (crl_score & CRL_SCORE_ISSUER_NAME))
1501 return 1;
1502 return 0;
1503}
1504
1505/* Retrieve CRL corresponding to current certificate.
1506 * If deltas enabled try to find a delta CRL too
1507 */
1508
1509static int
1510get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
1511{
1512 int ok;
1513 X509 *issuer = NULL;
1514 int crl_score = 0;
1515 unsigned int reasons;
1516 X509_CRL *crl = NULL, *dcrl = NULL;
1517 STACK_OF(X509_CRL) *skcrl;
1518 X509_NAME *nm = X509_get_issuer_name(x);
1519
1520 reasons = ctx->current_reasons;
1521 ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons,
1522 ctx->crls);
1523 if (ok)
1524 goto done;
1525
1526 /* Lookup CRLs from store */
1527 skcrl = X509_STORE_CTX_get1_crls(ctx, nm);
1528
1529 /* If no CRLs found and a near match from get_crl_sk use that */
1530 if (!skcrl && crl)
1531 goto done;
1532
1533 get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
1534
1535 sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
1536
1537done:
1538
1539 /* If we got any kind of CRL use it and return success */
1540 if (crl) {
1541 ctx->current_issuer = issuer;
1542 ctx->current_crl_score = crl_score;
1543 ctx->current_reasons = reasons;
1544 *pcrl = crl;
1545 *pdcrl = dcrl;
1546 return 1;
1547 }
1548
1549 return 0;
1550}
1551
1552/* Matches x509_verify_parent_signature() */
1553static int
1554x509_crl_verify_parent_signature(X509 *parent, X509_CRL *crl, int *error)
1555{
1556 EVP_PKEY *pkey;
1557 int cached;
1558 int ret = 0;
1559
1560 /* Use cached value if we have it */
1561 if ((cached = x509_issuer_cache_find(parent->hash, crl->hash)) >= 0) {
1562 if (cached == 0)
1563 *error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
1564 return cached;
1565 }
1566
1567 /* Check signature. Did parent sign crl? */
1568 if ((pkey = X509_get0_pubkey(parent)) == NULL) {
1569 *error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1570 return 0;
1571 }
1572 if (X509_CRL_verify(crl, pkey) <= 0)
1573 *error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
1574 else
1575 ret = 1;
1576
1577 /* Add result to cache */
1578 x509_issuer_cache_add(parent->hash, crl->hash, ret);
1579
1580 return ret;
1581}
1582
1583/* Check CRL validity */
1584static int
1585x509_vfy_check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
1586{
1587 X509 *issuer = NULL;
1588 int ok = 0, chnum, cnum;
1589
1590 cnum = ctx->error_depth;
1591 chnum = sk_X509_num(ctx->chain) - 1;
1592 /* if we have an alternative CRL issuer cert use that */
1593 if (ctx->current_issuer) {
1594 issuer = ctx->current_issuer;
1595 } else if (cnum < chnum) {
1596 /*
1597 * Else find CRL issuer: if not last certificate then issuer
1598 * is next certificate in chain.
1599 */
1600 issuer = sk_X509_value(ctx->chain, cnum + 1);
1601 } else {
1602 issuer = sk_X509_value(ctx->chain, chnum);
1603 /* If not self signed, can't check signature */
1604 if (!ctx->check_issued(ctx, issuer, issuer)) {
1605 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
1606 ok = ctx->verify_cb(0, ctx);
1607 if (!ok)
1608 goto err;
1609 }
1610 }
1611
1612 if (issuer) {
1613 /* Skip most tests for deltas because they have already
1614 * been done
1615 */
1616 if (!crl->base_crl_number) {
1617 /* Check for cRLSign bit if keyUsage present */
1618 if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
1619 !(issuer->ex_kusage & KU_CRL_SIGN)) {
1620 ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
1621 ok = ctx->verify_cb(0, ctx);
1622 if (!ok)
1623 goto err;
1624 }
1625
1626 if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
1627 ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
1628 ok = ctx->verify_cb(0, ctx);
1629 if (!ok)
1630 goto err;
1631 }
1632
1633 if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
1634 if (check_crl_path(ctx,
1635 ctx->current_issuer) <= 0) {
1636 ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
1637 ok = ctx->verify_cb(0, ctx);
1638 if (!ok)
1639 goto err;
1640 }
1641 }
1642
1643 if (crl->idp_flags & IDP_INVALID) {
1644 ctx->error = X509_V_ERR_INVALID_EXTENSION;
1645 ok = ctx->verify_cb(0, ctx);
1646 if (!ok)
1647 goto err;
1648 }
1649
1650
1651 }
1652
1653 if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
1654 ok = check_crl_time(ctx, crl, 1);
1655 if (!ok)
1656 goto err;
1657 }
1658
1659 if (!x509_crl_verify_parent_signature(issuer, crl, &ctx->error)) {
1660 ok = ctx->verify_cb(0, ctx);
1661 if (!ok)
1662 goto err;
1663 }
1664 }
1665
1666 ok = 1;
1667
1668 err:
1669 return ok;
1670}
1671
1672/* Check certificate against CRL */
1673static int
1674x509_vfy_cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
1675{
1676 int ok;
1677 X509_REVOKED *rev;
1678
1679 /* The rules changed for this... previously if a CRL contained
1680 * unhandled critical extensions it could still be used to indicate
1681 * a certificate was revoked. This has since been changed since
1682 * critical extension can change the meaning of CRL entries.
1683 */
1684 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) &&
1685 (crl->flags & EXFLAG_CRITICAL)) {
1686 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
1687 ok = ctx->verify_cb(0, ctx);
1688 if (!ok)
1689 return 0;
1690 }
1691 /* Look for serial number of certificate in CRL
1692 * If found make sure reason is not removeFromCRL.
1693 */
1694 if (X509_CRL_get0_by_cert(crl, &rev, x)) {
1695 if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
1696 return 2;
1697 ctx->error = X509_V_ERR_CERT_REVOKED;
1698 ok = ctx->verify_cb(0, ctx);
1699 if (!ok)
1700 return 0;
1701 }
1702
1703 return 1;
1704}
1705
1706int
1707x509_vfy_check_policy(X509_STORE_CTX *ctx)
1708{
1709 X509 *current_cert = NULL;
1710 int ret;
1711
1712 if (ctx->parent != NULL)
1713 return 1;
1714
1715 ret = X509_policy_check(ctx->chain, ctx->param->policies,
1716 ctx->param->flags, &current_cert);
1717 if (ret != X509_V_OK) {
1718 ctx->current_cert = current_cert;
1719 ctx->error = ret;
1720 if (ret == X509_V_ERR_OUT_OF_MEM)
1721 return 0;
1722 return ctx->verify_cb(0, ctx);
1723 }
1724
1725 if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
1726 ctx->current_cert = NULL;
1727 /*
1728 * Verification errors need to be "sticky", a callback may have
1729 * allowed an SSL handshake to continue despite an error, and
1730 * we must then remain in an error state. Therefore, we MUST
1731 * NOT clear earlier verification errors by setting the error
1732 * to X509_V_OK.
1733 */
1734 if (!ctx->verify_cb(2, ctx))
1735 return 0;
1736 }
1737
1738 return 1;
1739}
1740
1741/*
1742 * Inform the verify callback of an error.
1743 *
1744 * If x is not NULL it is the error cert, otherwise use the chain cert
1745 * at depth.
1746 *
1747 * If err is not X509_V_OK, that's the error value, otherwise leave
1748 * unchanged (presumably set by the caller).
1749 *
1750 * Returns 0 to abort verification with an error, non-zero to continue.
1751 */
1752static int
1753verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err)
1754{
1755 ctx->error_depth = depth;
1756 ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth);
1757 if (err != X509_V_OK)
1758 ctx->error = err;
1759 return ctx->verify_cb(0, ctx);
1760}
1761
1762/*
1763 * Check certificate validity times.
1764 *
1765 * If depth >= 0, invoke verification callbacks on error, otherwise just return
1766 * the validation status.
1767 *
1768 * Return 1 on success, 0 otherwise.
1769 */
1770int
1771x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth)
1772{
1773 time_t ptime;
1774 int i;
1775
1776 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
1777 ptime = ctx->param->check_time;
1778 else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
1779 return 1;
1780 else
1781 ptime = time(NULL);
1782
1783 i = X509_cmp_time(X509_get_notBefore(x), &ptime);
1784
1785 if (i >= 0 && depth < 0)
1786 return 0;
1787 if (i == 0 && !verify_cb_cert(ctx, x, depth,
1788 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD))
1789 return 0;
1790 if (i > 0 && !verify_cb_cert(ctx, x, depth,
1791 X509_V_ERR_CERT_NOT_YET_VALID))
1792 return 0;
1793
1794 i = X509_cmp_time_internal(X509_get_notAfter(x), &ptime, 1);
1795
1796 if (i <= 0 && depth < 0)
1797 return 0;
1798 if (i == 0 && !verify_cb_cert(ctx, x, depth,
1799 X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD))
1800 return 0;
1801 if (i < 0 && !verify_cb_cert(ctx, x, depth,
1802 X509_V_ERR_CERT_HAS_EXPIRED))
1803 return 0;
1804
1805 return 1;
1806}
1807
1808static int
1809x509_vfy_internal_verify(X509_STORE_CTX *ctx, int chain_verified)
1810{
1811 int n = sk_X509_num(ctx->chain) - 1;
1812 X509 *xi = sk_X509_value(ctx->chain, n);
1813 X509 *xs;
1814
1815 if (ctx->check_issued(ctx, xi, xi))
1816 xs = xi;
1817 else {
1818 if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
1819 xs = xi;
1820 goto check_cert;
1821 }
1822 if (n <= 0)
1823 return verify_cb_cert(ctx, xi, 0,
1824 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
1825 n--;
1826 ctx->error_depth = n;
1827 xs = sk_X509_value(ctx->chain, n);
1828 }
1829
1830 /*
1831 * Do not clear ctx->error=0, it must be "sticky", only the
1832 * user's callback is allowed to reset errors (at its own
1833 * peril).
1834 */
1835 while (n >= 0) {
1836
1837 /*
1838 * Skip signature check for self signed certificates
1839 * unless explicitly asked for. It doesn't add any
1840 * security and just wastes time. If the issuer's
1841 * public key is unusable, report the issuer
1842 * certificate and its depth (rather than the depth of
1843 * the subject).
1844 */
1845 if (!chain_verified && ( xs != xi ||
1846 (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
1847 EVP_PKEY *pkey;
1848 if ((pkey = X509_get_pubkey(xi)) == NULL) {
1849 if (!verify_cb_cert(ctx, xi, xi != xs ? n+1 : n,
1850 X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY))
1851 return 0;
1852 } else if (X509_verify(xs, pkey) <= 0) {
1853 if (!verify_cb_cert(ctx, xs, n,
1854 X509_V_ERR_CERT_SIGNATURE_FAILURE)) {
1855 EVP_PKEY_free(pkey);
1856 return 0;
1857 }
1858 }
1859 EVP_PKEY_free(pkey);
1860 }
1861check_cert:
1862 /* Calls verify callback as needed */
1863 if (!chain_verified && !x509_check_cert_time(ctx, xs, n))
1864 return 0;
1865
1866 /*
1867 * Signal success at this depth. However, the
1868 * previous error (if any) is retained.
1869 */
1870 ctx->current_issuer = xi;
1871 ctx->current_cert = xs;
1872 ctx->error_depth = n;
1873 if (!ctx->verify_cb(1, ctx))
1874 return 0;
1875
1876 if (--n >= 0) {
1877 xi = xs;
1878 xs = sk_X509_value(ctx->chain, n);
1879 }
1880 }
1881 return 1;
1882}
1883
1884static int
1885internal_verify(X509_STORE_CTX *ctx)
1886{
1887 return x509_vfy_internal_verify(ctx, 0);
1888}
1889
1890/*
1891 * Internal verify, but with a chain where the verification
1892 * math has already been performed.
1893 */
1894int
1895x509_vfy_callback_indicate_completion(X509_STORE_CTX *ctx)
1896{
1897 return x509_vfy_internal_verify(ctx, 1);
1898}
1899
1900int
1901X509_cmp_current_time(const ASN1_TIME *ctm)
1902{
1903 return X509_cmp_time(ctm, NULL);
1904}
1905LCRYPTO_ALIAS(X509_cmp_current_time);
1906
1907/*
1908 * Compare a possibly unvalidated ASN1_TIME string against a time_t
1909 * using RFC 5280 rules for the time string. If *cmp_time is NULL
1910 * the current system time is used.
1911 *
1912 * XXX NOTE that unlike what you expect a "cmp" function to do in C,
1913 * XXX this one is "special", and returns 0 for error.
1914 *
1915 * Returns:
1916 * -1 if the ASN1_time is earlier than OR the same as *cmp_time.
1917 * 1 if the ASN1_time is later than *cmp_time.
1918 * 0 on error.
1919 */
1920static int
1921X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int is_notafter)
1922{
1923 time_t compare, cert_time;
1924
1925 if (cmp_time == NULL)
1926 compare = time(NULL);
1927 else
1928 compare = *cmp_time;
1929
1930 if (!x509_verify_asn1_time_to_time_t(ctm, is_notafter, &cert_time))
1931 return 0; /* invalid time */
1932
1933 if (cert_time <= compare)
1934 return -1; /* 0 is used for error, so map same to less than */
1935
1936 return 1;
1937}
1938
1939int
1940X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
1941{
1942 return X509_cmp_time_internal(ctm, cmp_time, 0);
1943}
1944LCRYPTO_ALIAS(X509_cmp_time);
1945
1946
1947ASN1_TIME *
1948X509_gmtime_adj(ASN1_TIME *s, long adj)
1949{
1950 return X509_time_adj(s, adj, NULL);
1951}
1952LCRYPTO_ALIAS(X509_gmtime_adj);
1953
1954ASN1_TIME *
1955X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_time)
1956{
1957 return X509_time_adj_ex(s, 0, offset_sec, in_time);
1958}
1959LCRYPTO_ALIAS(X509_time_adj);
1960
1961ASN1_TIME *
1962X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *in_time)
1963{
1964 time_t t;
1965 if (in_time == NULL)
1966 t = time(NULL);
1967 else
1968 t = *in_time;
1969
1970 return ASN1_TIME_adj(s, t, offset_day, offset_sec);
1971}
1972LCRYPTO_ALIAS(X509_time_adj_ex);
1973
1974int
1975X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
1976{
1977 EVP_PKEY *ktmp = NULL, *ktmp2;
1978 int i, j;
1979
1980 if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey))
1981 return 1;
1982
1983 for (i = 0; i < sk_X509_num(chain); i++) {
1984 ktmp = X509_get0_pubkey(sk_X509_value(chain, i));
1985 if (ktmp == NULL) {
1986 X509error(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
1987 return 0;
1988 }
1989 if (!EVP_PKEY_missing_parameters(ktmp))
1990 break;
1991 else
1992 ktmp = NULL;
1993 }
1994 if (ktmp == NULL) {
1995 X509error(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
1996 return 0;
1997 }
1998
1999 /* first, populate the other certs */
2000 for (j = i - 1; j >= 0; j--) {
2001 if ((ktmp2 = X509_get0_pubkey(sk_X509_value(chain, j))) == NULL)
2002 return 0;
2003 if (!EVP_PKEY_copy_parameters(ktmp2, ktmp))
2004 return 0;
2005 }
2006
2007 if (pkey != NULL)
2008 if (!EVP_PKEY_copy_parameters(pkey, ktmp))
2009 return 0;
2010 return 1;
2011}
2012LCRYPTO_ALIAS(X509_get_pubkey_parameters);
2013
2014int
2015X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
2016 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
2017{
2018 /* This function is (usually) called only once, by
2019 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
2020 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX,
2021 argl, argp, new_func, dup_func, free_func);
2022}
2023LCRYPTO_ALIAS(X509_STORE_CTX_get_ex_new_index);
2024
2025int
2026X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
2027{
2028 return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
2029}
2030LCRYPTO_ALIAS(X509_STORE_CTX_set_ex_data);
2031
2032void *
2033X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
2034{
2035 return CRYPTO_get_ex_data(&ctx->ex_data, idx);
2036}
2037LCRYPTO_ALIAS(X509_STORE_CTX_get_ex_data);
2038
2039int
2040X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
2041{
2042 return ctx->error;
2043}
2044LCRYPTO_ALIAS(X509_STORE_CTX_get_error);
2045
2046void
2047X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
2048{
2049 ctx->error = err;
2050}
2051LCRYPTO_ALIAS(X509_STORE_CTX_set_error);
2052
2053int
2054X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
2055{
2056 return ctx->error_depth;
2057}
2058LCRYPTO_ALIAS(X509_STORE_CTX_get_error_depth);
2059
2060void
2061X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth)
2062{
2063 ctx->error_depth = depth;
2064}
2065LCRYPTO_ALIAS(X509_STORE_CTX_set_error_depth);
2066
2067X509 *
2068X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
2069{
2070 return ctx->current_cert;
2071}
2072LCRYPTO_ALIAS(X509_STORE_CTX_get_current_cert);
2073
2074void
2075X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x)
2076{
2077 ctx->current_cert = x;
2078}
2079LCRYPTO_ALIAS(X509_STORE_CTX_set_current_cert);
2080
2081STACK_OF(X509) *
2082X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
2083{
2084 return ctx->chain;
2085}
2086LCRYPTO_ALIAS(X509_STORE_CTX_get_chain);
2087
2088STACK_OF(X509) *
2089X509_STORE_CTX_get0_chain(X509_STORE_CTX *xs)
2090{
2091 return xs->chain;
2092}
2093LCRYPTO_ALIAS(X509_STORE_CTX_get0_chain);
2094
2095STACK_OF(X509) *
2096X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
2097{
2098 int i;
2099 X509 *x;
2100 STACK_OF(X509) *chain;
2101
2102 if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain)))
2103 return NULL;
2104 for (i = 0; i < sk_X509_num(chain); i++) {
2105 x = sk_X509_value(chain, i);
2106 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
2107 }
2108 return chain;
2109}
2110LCRYPTO_ALIAS(X509_STORE_CTX_get1_chain);
2111
2112X509 *
2113X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
2114{
2115 return ctx->current_issuer;
2116}
2117LCRYPTO_ALIAS(X509_STORE_CTX_get0_current_issuer);
2118
2119X509_CRL *
2120X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
2121{
2122 return ctx->current_crl;
2123}
2124LCRYPTO_ALIAS(X509_STORE_CTX_get0_current_crl);
2125
2126X509_STORE_CTX *
2127X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
2128{
2129 return ctx->parent;
2130}
2131LCRYPTO_ALIAS(X509_STORE_CTX_get0_parent_ctx);
2132
2133X509_STORE *
2134X509_STORE_CTX_get0_store(X509_STORE_CTX *xs)
2135{
2136 return xs->store;
2137}
2138LCRYPTO_ALIAS(X509_STORE_CTX_get0_store);
2139
2140void
2141X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
2142{
2143 ctx->cert = x;
2144}
2145LCRYPTO_ALIAS(X509_STORE_CTX_set_cert);
2146
2147void
2148X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
2149{
2150 ctx->untrusted = sk;
2151}
2152LCRYPTO_ALIAS(X509_STORE_CTX_set_chain);
2153
2154void
2155X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
2156{
2157 ctx->crls = sk;
2158}
2159LCRYPTO_ALIAS(X509_STORE_CTX_set0_crls);
2160
2161/*
2162 * This function is used to set the X509_STORE_CTX purpose and trust
2163 * values. This is intended to be used when another structure has its
2164 * own trust and purpose values which (if set) will be inherited by
2165 * the ctx. If they aren't set then we will usually have a default
2166 * purpose in mind which should then be used to set the trust value.
2167 * An example of this is SSL use: an SSL structure will have its own
2168 * purpose and trust settings which the application can set: if they
2169 * aren't set then we use the default of SSL client/server.
2170 */
2171int
2172X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose_id)
2173{
2174 const X509_PURPOSE *purpose;
2175 int idx;
2176
2177 /* XXX - Match wacky/documented behavior. Do we need to keep this? */
2178 if (purpose_id == 0)
2179 return 1;
2180
2181 if (purpose_id < X509_PURPOSE_MIN || purpose_id > X509_PURPOSE_MAX) {
2182 X509error(X509_R_UNKNOWN_PURPOSE_ID);
2183 return 0;
2184 }
2185 idx = purpose_id - X509_PURPOSE_MIN;
2186 if ((purpose = X509_PURPOSE_get0(idx)) == NULL) {
2187 X509error(X509_R_UNKNOWN_PURPOSE_ID);
2188 return 0;
2189 }
2190
2191 /* XXX - Succeeding while ignoring purpose_id and trust is awful. */
2192 if (ctx->param->purpose == 0)
2193 ctx->param->purpose = purpose_id;
2194 if (ctx->param->trust == 0)
2195 ctx->param->trust = X509_PURPOSE_get_trust(purpose);
2196
2197 return 1;
2198}
2199LCRYPTO_ALIAS(X509_STORE_CTX_set_purpose);
2200
2201int
2202X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust_id)
2203{
2204 /* XXX - Match wacky/documented behavior. Do we need to keep this? */
2205 if (trust_id == 0)
2206 return 1;
2207
2208 if (trust_id < X509_TRUST_MIN || trust_id > X509_TRUST_MAX) {
2209 X509error(X509_R_UNKNOWN_TRUST_ID);
2210 return 0;
2211 }
2212
2213 /* XXX - Succeeding while ignoring the trust_id is awful. */
2214 if (ctx->param->trust == 0)
2215 ctx->param->trust = trust_id;
2216
2217 return 1;
2218}
2219LCRYPTO_ALIAS(X509_STORE_CTX_set_trust);
2220
2221X509_STORE_CTX *
2222X509_STORE_CTX_new(void)
2223{
2224 X509_STORE_CTX *ctx;
2225
2226 ctx = calloc(1, sizeof(X509_STORE_CTX));
2227 if (!ctx) {
2228 X509error(ERR_R_MALLOC_FAILURE);
2229 return NULL;
2230 }
2231 return ctx;
2232}
2233LCRYPTO_ALIAS(X509_STORE_CTX_new);
2234
2235void
2236X509_STORE_CTX_free(X509_STORE_CTX *ctx)
2237{
2238 if (ctx == NULL)
2239 return;
2240
2241 X509_STORE_CTX_cleanup(ctx);
2242 free(ctx);
2243}
2244LCRYPTO_ALIAS(X509_STORE_CTX_free);
2245
2246int
2247X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *leaf,
2248 STACK_OF(X509) *untrusted)
2249{
2250 int param_ret = 1;
2251
2252 /*
2253 * Make sure everything is initialized properly even in case of an
2254 * early return due to an error.
2255 *
2256 * While this 'ctx' can be reused, X509_STORE_CTX_cleanup() will have
2257 * freed everything and memset ex_data anyway. This also allows us
2258 * to safely use X509_STORE_CTX variables from the stack which will
2259 * have uninitialized data.
2260 */
2261 memset(ctx, 0, sizeof(*ctx));
2262
2263 /*
2264 * Start with this set to not valid - it will be set to valid
2265 * in X509_verify_cert.
2266 */
2267 ctx->error = X509_V_ERR_INVALID_CALL;
2268
2269 /*
2270 * Set values other than 0. Keep this in the same order as
2271 * X509_STORE_CTX except for values that may fail. All fields that
2272 * may fail should go last to make sure 'ctx' is as consistent as
2273 * possible even on early exits.
2274 */
2275 ctx->store = store;
2276 ctx->cert = leaf;
2277 ctx->untrusted = untrusted;
2278
2279 if (store && store->verify)
2280 ctx->verify = store->verify;
2281 else
2282 ctx->verify = internal_verify;
2283
2284 if (store && store->verify_cb)
2285 ctx->verify_cb = store->verify_cb;
2286 else
2287 ctx->verify_cb = null_callback;
2288
2289 ctx->get_issuer = X509_STORE_CTX_get1_issuer;
2290 ctx->check_issued = check_issued;
2291
2292 ctx->param = X509_VERIFY_PARAM_new();
2293 if (!ctx->param) {
2294 X509error(ERR_R_MALLOC_FAILURE);
2295 return 0;
2296 }
2297
2298 /* Inherit callbacks and flags from X509_STORE if not set
2299 * use defaults.
2300 */
2301 if (store)
2302 param_ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
2303 else
2304 ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE;
2305
2306 if (param_ret)
2307 param_ret = X509_VERIFY_PARAM_inherit(ctx->param,
2308 X509_VERIFY_PARAM_lookup("default"));
2309
2310 if (param_ret == 0) {
2311 X509error(ERR_R_MALLOC_FAILURE);
2312 return 0;
2313 }
2314
2315 if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
2316 &ctx->ex_data) == 0) {
2317 X509error(ERR_R_MALLOC_FAILURE);
2318 return 0;
2319 }
2320 return 1;
2321}
2322LCRYPTO_ALIAS(X509_STORE_CTX_init);
2323
2324/* Set alternative lookup method: just a STACK of trusted certificates.
2325 * This avoids X509_STORE nastiness where it isn't needed.
2326 */
2327
2328void
2329X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *trusted)
2330{
2331 X509_STORE_CTX_set0_trusted_stack(ctx, trusted);
2332}
2333LCRYPTO_ALIAS(X509_STORE_CTX_trusted_stack);
2334
2335void
2336X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *trusted)
2337{
2338 ctx->trusted = trusted;
2339 ctx->get_issuer = x509_vfy_get_trusted_issuer;
2340}
2341LCRYPTO_ALIAS(X509_STORE_CTX_set0_trusted_stack);
2342
2343void
2344X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
2345{
2346 if (ctx->param != NULL) {
2347 if (ctx->parent == NULL)
2348 X509_VERIFY_PARAM_free(ctx->param);
2349 ctx->param = NULL;
2350 }
2351 if (ctx->chain != NULL) {
2352 sk_X509_pop_free(ctx->chain, X509_free);
2353 ctx->chain = NULL;
2354 }
2355 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &ctx->ex_data);
2356 memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
2357}
2358LCRYPTO_ALIAS(X509_STORE_CTX_cleanup);
2359
2360void
2361X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
2362{
2363 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
2364}
2365LCRYPTO_ALIAS(X509_STORE_CTX_set_depth);
2366
2367void
2368X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
2369{
2370 X509_VERIFY_PARAM_set_flags(ctx->param, flags);
2371}
2372LCRYPTO_ALIAS(X509_STORE_CTX_set_flags);
2373
2374void
2375X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
2376{
2377 X509_VERIFY_PARAM_set_time(ctx->param, t);
2378}
2379LCRYPTO_ALIAS(X509_STORE_CTX_set_time);
2380
2381int
2382(*X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx))(int, X509_STORE_CTX *)
2383{
2384 return ctx->verify_cb;
2385}
2386LCRYPTO_ALIAS(X509_STORE_CTX_get_verify_cb);
2387
2388void
2389X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
2390 int (*verify_cb)(int, X509_STORE_CTX *))
2391{
2392 ctx->verify_cb = verify_cb;
2393}
2394LCRYPTO_ALIAS(X509_STORE_CTX_set_verify_cb);
2395
2396int
2397(*X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx))(X509_STORE_CTX *)
2398{
2399 return ctx->verify;
2400}
2401LCRYPTO_ALIAS(X509_STORE_CTX_get_verify);
2402
2403void
2404X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, int (*verify)(X509_STORE_CTX *))
2405{
2406 ctx->verify = verify;
2407}
2408LCRYPTO_ALIAS(X509_STORE_CTX_set_verify);
2409
2410X509_STORE_CTX_check_issued_fn
2411X509_STORE_get_check_issued(X509_STORE *store)
2412{
2413 return store->check_issued;
2414}
2415LCRYPTO_ALIAS(X509_STORE_get_check_issued);
2416
2417void
2418X509_STORE_set_check_issued(X509_STORE *store,
2419 X509_STORE_CTX_check_issued_fn check_issued)
2420{
2421 store->check_issued = check_issued;
2422}
2423LCRYPTO_ALIAS(X509_STORE_set_check_issued);
2424
2425X509_STORE_CTX_check_issued_fn
2426X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx)
2427{
2428 return ctx->check_issued;
2429}
2430LCRYPTO_ALIAS(X509_STORE_CTX_get_check_issued);
2431
2432X509 *
2433X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
2434{
2435 return ctx->cert;
2436}
2437LCRYPTO_ALIAS(X509_STORE_CTX_get0_cert);
2438
2439STACK_OF(X509) *
2440X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
2441{
2442 return ctx->untrusted;
2443}
2444LCRYPTO_ALIAS(X509_STORE_CTX_get0_untrusted);
2445
2446void
2447X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
2448{
2449 ctx->untrusted = sk;
2450}
2451LCRYPTO_ALIAS(X509_STORE_CTX_set0_untrusted);
2452
2453void
2454X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
2455{
2456 sk_X509_pop_free(ctx->chain, X509_free);
2457 ctx->chain = sk;
2458}
2459LCRYPTO_ALIAS(X509_STORE_CTX_set0_verified_chain);
2460
2461int
2462X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
2463{
2464 return ctx->num_untrusted;
2465}
2466LCRYPTO_ALIAS(X509_STORE_CTX_get_num_untrusted);
2467
2468int
2469X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
2470{
2471 const X509_VERIFY_PARAM *param;
2472 param = X509_VERIFY_PARAM_lookup(name);
2473 if (!param)
2474 return 0;
2475 return X509_VERIFY_PARAM_inherit(ctx->param, param);
2476}
2477LCRYPTO_ALIAS(X509_STORE_CTX_set_default);
2478
2479X509_VERIFY_PARAM *
2480X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
2481{
2482 return ctx->param;
2483}
2484LCRYPTO_ALIAS(X509_STORE_CTX_get0_param);
2485
2486void
2487X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
2488{
2489 if (ctx->param)
2490 X509_VERIFY_PARAM_free(ctx->param);
2491 ctx->param = param;
2492}
2493LCRYPTO_ALIAS(X509_STORE_CTX_set0_param);
2494
2495/*
2496 * Check if |bits| are adequate for |security level|.
2497 * Returns 1 if ok, 0 otherwise.
2498 */
2499static int
2500enough_bits_for_security_level(int bits, int level)
2501{
2502 /*
2503 * Sigh. OpenSSL does this silly squashing, so we will
2504 * too. Derp for Derp compatibility being important.
2505 */
2506 if (level < 0)
2507 level = 0;
2508 if (level > 5)
2509 level = 5;
2510
2511 switch (level) {
2512 case 0:
2513 return 1;
2514 case 1:
2515 return bits >= 80;
2516 case 2:
2517 return bits >= 112;
2518 case 3:
2519 return bits >= 128;
2520 case 4:
2521 return bits >= 192;
2522 case 5:
2523 return bits >= 256;
2524 default:
2525 return 0;
2526 }
2527}
2528
2529/*
2530 * Check whether the public key of |cert| meets the security level of |ctx|.
2531 *
2532 * Returns 1 on success, 0 otherwise.
2533 */
2534static int
2535check_key_level(X509_STORE_CTX *ctx, X509 *cert)
2536{
2537 EVP_PKEY *pkey;
2538 int bits;
2539
2540 /* Unsupported or malformed keys are not secure */
2541 if ((pkey = X509_get0_pubkey(cert)) == NULL)
2542 return 0;
2543
2544 if ((bits = EVP_PKEY_security_bits(pkey)) <= 0)
2545 return 0;
2546
2547 return enough_bits_for_security_level(bits, ctx->param->security_level);
2548}
2549
2550/*
2551 * Check whether the signature digest algorithm of |cert| meets the security
2552 * level of |ctx|. Do not check trust anchors (self-signed or not).
2553 *
2554 * Returns 1 on success, 0 otherwise.
2555 */
2556static int
2557check_sig_level(X509_STORE_CTX *ctx, X509 *cert)
2558{
2559 int bits;
2560
2561 if (!X509_get_signature_info(cert, NULL, NULL, &bits, NULL))
2562 return 0;
2563
2564 return enough_bits_for_security_level(bits, ctx->param->security_level);
2565}
2566
2567int
2568x509_vfy_check_security_level(X509_STORE_CTX *ctx)
2569{
2570 int num = sk_X509_num(ctx->chain);
2571 int i;
2572
2573 if (ctx->param->security_level <= 0)
2574 return 1;
2575
2576 for (i = 0; i < num; i++) {
2577 X509 *cert = sk_X509_value(ctx->chain, i);
2578
2579 /*
2580 * We've already checked the security of the leaf key, so here
2581 * we only check the security of issuer keys.
2582 */
2583 if (i > 0) {
2584 if (!check_key_level(ctx, cert) &&
2585 !verify_cb_cert(ctx, cert, i,
2586 X509_V_ERR_CA_KEY_TOO_SMALL))
2587 return 0;
2588 }
2589
2590 /*
2591 * We also check the signature algorithm security of all certs
2592 * except those of the trust anchor at index num - 1.
2593 */
2594 if (i == num - 1)
2595 break;
2596
2597 if (!check_sig_level(ctx, cert) &&
2598 !verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK))
2599 return 0;
2600 }
2601 return 1;
2602}
diff --git a/src/lib/libcrypto/x509/x509_vfy.h b/src/lib/libcrypto/x509/x509_vfy.h
deleted file mode 100644
index 7058bbc5b0..0000000000
--- a/src/lib/libcrypto/x509/x509_vfy.h
+++ /dev/null
@@ -1,463 +0,0 @@
1/* $OpenBSD: x509_vfy.h,v 1.70 2025/03/09 15:20:20 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#ifndef HEADER_X509_H
60#include <openssl/x509.h>
61/* openssl/x509.h ends up #include-ing this file at about the only
62 * appropriate moment. */
63#endif
64
65#ifndef HEADER_X509_VFY_H
66#define HEADER_X509_VFY_H
67
68#include <openssl/opensslconf.h>
69
70#ifndef OPENSSL_NO_LHASH
71#include <openssl/lhash.h>
72#endif
73#include <openssl/bio.h>
74#include <openssl/crypto.h>
75
76#ifdef __cplusplus
77extern "C" {
78#endif
79
80/*
81 * SSL_CTX -> X509_STORE
82 * -> X509_LOOKUP
83 * ->X509_LOOKUP_METHOD
84 * -> X509_LOOKUP
85 * ->X509_LOOKUP_METHOD
86 *
87 * SSL -> X509_STORE_CTX
88 * ->X509_STORE
89 *
90 * The X509_STORE holds the tables etc for verification stuff.
91 * A X509_STORE_CTX is used while validating a single certificate.
92 * The X509_STORE has X509_LOOKUPs for looking up certs.
93 * The X509_STORE then calls a function to actually verify the
94 * certificate chain.
95 */
96
97typedef enum {
98 X509_LU_NONE,
99 X509_LU_X509,
100 X509_LU_CRL,
101} X509_LOOKUP_TYPE;
102
103
104DECLARE_STACK_OF(X509_LOOKUP)
105DECLARE_STACK_OF(X509_OBJECT)
106DECLARE_STACK_OF(X509_VERIFY_PARAM)
107
108/* XXX - unused in OpenSSL. Can we remove this? */
109typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID;
110
111
112int X509_STORE_set_depth(X509_STORE *store, int depth);
113
114void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
115
116#define X509_STORE_CTX_set_app_data(ctx,data) \
117 X509_STORE_CTX_set_ex_data(ctx,0,data)
118#define X509_STORE_CTX_get_app_data(ctx) \
119 X509_STORE_CTX_get_ex_data(ctx,0)
120
121#define X509_L_FILE_LOAD 1
122#define X509_L_ADD_DIR 2
123#define X509_L_MEM 3
124
125#define X509_LOOKUP_load_file(x,name,type) \
126 X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
127
128#define X509_LOOKUP_add_dir(x,name,type) \
129 X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
130
131#define X509_LOOKUP_add_mem(x,iov,type) \
132 X509_LOOKUP_ctrl((x),X509_L_MEM,(const char *)(iov),\
133 (long)(type),NULL)
134
135#define X509_V_OK 0
136#define X509_V_ERR_UNSPECIFIED 1
137#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2
138#define X509_V_ERR_UNABLE_TO_GET_CRL 3
139#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4
140#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5
141#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
142#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
143#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
144#define X509_V_ERR_CERT_NOT_YET_VALID 9
145#define X509_V_ERR_CERT_HAS_EXPIRED 10
146#define X509_V_ERR_CRL_NOT_YET_VALID 11
147#define X509_V_ERR_CRL_HAS_EXPIRED 12
148#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13
149#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14
150#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15
151#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16
152#define X509_V_ERR_OUT_OF_MEM 17
153#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18
154#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19
155#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20
156#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
157#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
158#define X509_V_ERR_CERT_REVOKED 23
159#define X509_V_ERR_INVALID_CA 24
160#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
161#define X509_V_ERR_INVALID_PURPOSE 26
162#define X509_V_ERR_CERT_UNTRUSTED 27
163#define X509_V_ERR_CERT_REJECTED 28
164/* These are 'informational' when looking for issuer cert */
165#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29
166#define X509_V_ERR_AKID_SKID_MISMATCH 30
167#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31
168#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32
169
170#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33
171#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34
172#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35
173#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36
174#define X509_V_ERR_INVALID_NON_CA 37
175#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
176#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
177#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
178
179#define X509_V_ERR_INVALID_EXTENSION 41
180#define X509_V_ERR_INVALID_POLICY_EXTENSION 42
181#define X509_V_ERR_NO_EXPLICIT_POLICY 43
182#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44
183#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45
184
185#define X509_V_ERR_UNNESTED_RESOURCE 46
186
187#define X509_V_ERR_PERMITTED_VIOLATION 47
188#define X509_V_ERR_EXCLUDED_VIOLATION 48
189#define X509_V_ERR_SUBTREE_MINMAX 49
190#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
191#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
192#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
193#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54
194
195/* The application is not happy */
196#define X509_V_ERR_APPLICATION_VERIFICATION 50
197
198/* Host, email and IP check errors */
199#define X509_V_ERR_HOSTNAME_MISMATCH 62
200#define X509_V_ERR_EMAIL_MISMATCH 63
201#define X509_V_ERR_IP_ADDRESS_MISMATCH 64
202
203/* Caller error */
204#define X509_V_ERR_INVALID_CALL 65
205/* Issuer lookup error */
206#define X509_V_ERR_STORE_LOOKUP 66
207
208/* Security level errors */
209#define X509_V_ERR_EE_KEY_TOO_SMALL 67
210#define X509_V_ERR_CA_KEY_TOO_SMALL 68
211#define X509_V_ERR_CA_MD_TOO_WEAK 69
212
213/* Certificate verify flags */
214
215/* Deprecated in 1.1.0, has no effect. Various FFI bindings still expose it. */
216#define X509_V_FLAG_CB_ISSUER_CHECK 0x0
217/* Use check time instead of current time */
218#define X509_V_FLAG_USE_CHECK_TIME 0x2
219/* Lookup CRLs */
220#define X509_V_FLAG_CRL_CHECK 0x4
221/* Lookup CRLs for whole chain */
222#define X509_V_FLAG_CRL_CHECK_ALL 0x8
223/* Ignore unhandled critical extensions */
224#define X509_V_FLAG_IGNORE_CRITICAL 0x10
225/* Disable workarounds for broken certificates */
226#define X509_V_FLAG_X509_STRICT 0x20
227/* Enable proxy certificate validation */
228#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40
229/* Does nothing as its functionality has been enabled by default */
230#define X509_V_FLAG_POLICY_CHECK 0x80
231/* Policy variable require-explicit-policy */
232#define X509_V_FLAG_EXPLICIT_POLICY 0x100
233/* Policy variable inhibit-any-policy */
234#define X509_V_FLAG_INHIBIT_ANY 0x200
235/* Policy variable inhibit-policy-mapping */
236#define X509_V_FLAG_INHIBIT_MAP 0x400
237/* Notify callback that policy is OK */
238#define X509_V_FLAG_NOTIFY_POLICY 0x800
239/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
240#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000
241/* Delta CRL support */
242#define X509_V_FLAG_USE_DELTAS 0x2000
243/* Check selfsigned CA signature */
244#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000
245/* Use trusted store first */
246#define X509_V_FLAG_TRUSTED_FIRST 0x8000
247/* Allow partial chains if at least one certificate is in trusted store */
248#define X509_V_FLAG_PARTIAL_CHAIN 0x80000
249
250/* If the initial chain is not trusted, do not attempt to build an alternative
251 * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag
252 * will force the behaviour to match that of previous versions. */
253#define X509_V_FLAG_NO_ALT_CHAINS 0x100000
254
255/* Do not check certificate or CRL validity against current time. */
256#define X509_V_FLAG_NO_CHECK_TIME 0x200000
257
258/* Force the use of the legacy certificate verification */
259#define X509_V_FLAG_LEGACY_VERIFY 0x400000
260
261#define X509_VP_FLAG_DEFAULT 0x1
262#define X509_VP_FLAG_OVERWRITE 0x2
263#define X509_VP_FLAG_RESET_FLAGS 0x4
264#define X509_VP_FLAG_LOCKED 0x8
265#define X509_VP_FLAG_ONCE 0x10
266
267/*
268 * Obsolete internal use: mask of policy related options.
269 * This should really go away.
270 */
271#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
272 | X509_V_FLAG_EXPLICIT_POLICY \
273 | X509_V_FLAG_INHIBIT_ANY \
274 | X509_V_FLAG_INHIBIT_MAP)
275
276X509_OBJECT *X509_OBJECT_new(void);
277void X509_OBJECT_free(X509_OBJECT *a);
278int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
279 X509_NAME *name);
280X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
281 X509_LOOKUP_TYPE type, X509_NAME *name);
282X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x);
283X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a);
284X509 *X509_OBJECT_get0_X509(const X509_OBJECT *xo);
285X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *xo);
286
287X509_STORE *X509_STORE_new(void);
288void X509_STORE_free(X509_STORE *v);
289int X509_STORE_up_ref(X509_STORE *x);
290#define X509_STORE_get1_certs X509_STORE_CTX_get1_certs
291#define X509_STORE_get1_crls X509_STORE_CTX_get1_crls
292STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
293STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
294STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *xs);
295STACK_OF(X509_OBJECT) *X509_STORE_get1_objects(X509_STORE *xs);
296void *X509_STORE_get_ex_data(X509_STORE *xs, int idx);
297int X509_STORE_set_ex_data(X509_STORE *xs, int idx, void *data);
298
299#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \
300 CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \
301 (newf), (dupf), (freef))
302
303int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
304int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
305int X509_STORE_set_trust(X509_STORE *ctx, int trust);
306int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
307X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx);
308
309typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *);
310
311X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *);
312
313void X509_STORE_set_verify_cb(X509_STORE *ctx,
314 int (*verify_cb)(int, X509_STORE_CTX *));
315#define X509_STORE_set_verify_cb_func(ctx, func) \
316 X509_STORE_set_verify_cb((ctx), (func))
317
318typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx,
319 X509 *subject, X509 *issuer);
320
321X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *store);
322void X509_STORE_set_check_issued(X509_STORE *store,
323 X509_STORE_CTX_check_issued_fn check_issued);
324X509_STORE_CTX_check_issued_fn
325 X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx);
326
327X509_STORE_CTX *X509_STORE_CTX_new(void);
328
329int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
330
331void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
332int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
333 X509 *x509, STACK_OF(X509) *chain);
334X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx);
335STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *xs);
336X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *xs);
337STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx);
338void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
339void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
340void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
341void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
342
343X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, const X509_LOOKUP_METHOD *m);
344
345const X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
346const X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
347const X509_LOOKUP_METHOD *X509_LOOKUP_mem(void);
348
349int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
350int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
351
352int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
353 X509_NAME *name, X509_OBJECT *ret);
354#define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject
355X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs,
356 X509_LOOKUP_TYPE type, X509_NAME *name);
357
358int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
359 long argl, char **ret);
360
361int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
362int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
363int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
364
365void X509_LOOKUP_free(X509_LOOKUP *ctx);
366
367int X509_STORE_load_locations(X509_STORE *ctx,
368 const char *file, const char *dir);
369int X509_STORE_load_mem(X509_STORE *ctx, void *buf, int len);
370int X509_STORE_set_default_paths(X509_STORE *ctx);
371
372int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
373 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
374int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
375void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
376int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
377void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
378int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
379void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth);
380X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
381void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x);
382X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
383X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
384X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
385STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
386STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
387void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
388void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
389void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk);
390int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
391int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
392void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
393void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
394 time_t t);
395void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
396int (*X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx))(X509_STORE_CTX *);
397void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx,
398 int (*verify)(X509_STORE_CTX *));
399int (*X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx))(int, X509_STORE_CTX *);
400void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
401 int (*verify_cb)(int, X509_STORE_CTX *));
402
403typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *);
404
405void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify);
406X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx);
407#define X509_STORE_set_verify_func(ctx, func) \
408 X509_STORE_set_verify((ctx), (func))
409
410int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx);
411
412X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
413void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
414int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
415
416/* X509_VERIFY_PARAM functions */
417
418X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
419void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
420int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
421 const X509_VERIFY_PARAM *from);
422int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
423 const X509_VERIFY_PARAM *from);
424int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
425int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
426int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
427 unsigned long flags);
428unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
429int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
430int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
431void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
432void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level);
433time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param);
434void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
435int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
436 ASN1_OBJECT *policy);
437int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
438 STACK_OF(ASN1_OBJECT) *policies);
439int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
440int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const char *name,
441 size_t namelen);
442int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, const char *name,
443 size_t namelen);
444void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
445 unsigned int flags);
446char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param);
447int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
448 size_t emaillen);
449int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
450 size_t iplen);
451int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc);
452const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);
453const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id);
454int X509_VERIFY_PARAM_get_count(void);
455
456int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
457const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
458void X509_VERIFY_PARAM_table_cleanup(void);
459
460#ifdef __cplusplus
461}
462#endif
463#endif
diff --git a/src/lib/libcrypto/x509/x509_vpm.c b/src/lib/libcrypto/x509/x509_vpm.c
deleted file mode 100644
index 9efe473fc3..0000000000
--- a/src/lib/libcrypto/x509/x509_vpm.c
+++ /dev/null
@@ -1,743 +0,0 @@
1/* $OpenBSD: x509_vpm.c,v 1.55 2025/03/19 17:11:21 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 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 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/buffer.h>
63#include <openssl/crypto.h>
64#include <openssl/err.h>
65#include <openssl/lhash.h>
66#include <openssl/stack.h>
67#include <openssl/x509.h>
68#include <openssl/x509v3.h>
69
70#include "x509_local.h"
71
72/* X509_VERIFY_PARAM functions */
73
74int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
75 size_t emaillen);
76int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
77 size_t iplen);
78
79#define SET_HOST 0
80#define ADD_HOST 1
81
82static void
83str_free(char *s)
84{
85 free(s);
86}
87
88static STACK_OF(OPENSSL_STRING) *
89sk_OPENSSL_STRING_deep_copy(const STACK_OF(OPENSSL_STRING) *sk)
90{
91 STACK_OF(OPENSSL_STRING) *new;
92 char *copy = NULL;
93 int i;
94
95 if ((new = sk_OPENSSL_STRING_new_null()) == NULL)
96 goto err;
97
98 for (i = 0; i < sk_OPENSSL_STRING_num(sk); i++) {
99 if ((copy = strdup(sk_OPENSSL_STRING_value(sk, i))) == NULL)
100 goto err;
101 if (sk_OPENSSL_STRING_push(new, copy) <= 0)
102 goto err;
103 copy = NULL;
104 }
105
106 return new;
107
108 err:
109 sk_OPENSSL_STRING_pop_free(new, str_free);
110 free(copy);
111
112 return NULL;
113}
114
115static int
116x509_param_set_hosts_internal(X509_VERIFY_PARAM *param, int mode,
117 const char *name, size_t namelen)
118{
119 char *copy;
120
121 if (name != NULL && namelen == 0)
122 namelen = strlen(name);
123 /*
124 * Refuse names with embedded NUL bytes.
125 */
126 if (name && memchr(name, '\0', namelen))
127 return 0;
128
129 if (mode == SET_HOST && param->hosts) {
130 sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
131 param->hosts = NULL;
132 }
133 if (name == NULL || namelen == 0)
134 return 1;
135 copy = strndup(name, namelen);
136 if (copy == NULL)
137 return 0;
138
139 if (param->hosts == NULL &&
140 (param->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
141 free(copy);
142 return 0;
143 }
144
145 if (!sk_OPENSSL_STRING_push(param->hosts, copy)) {
146 free(copy);
147 if (sk_OPENSSL_STRING_num(param->hosts) == 0) {
148 sk_OPENSSL_STRING_free(param->hosts);
149 param->hosts = NULL;
150 }
151 return 0;
152 }
153
154 return 1;
155}
156
157static void
158x509_verify_param_zero(X509_VERIFY_PARAM *param)
159{
160 if (!param)
161 return;
162
163 free(param->name);
164 param->name = NULL;
165 param->purpose = 0;
166 param->trust = 0;
167 /*param->inh_flags = X509_VP_FLAG_DEFAULT;*/
168 param->inh_flags = 0;
169 param->flags = 0;
170 param->depth = -1;
171 sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
172 param->policies = NULL;
173 sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
174 param->hosts = NULL;
175 free(param->peername);
176 param->peername = NULL;
177 free(param->email);
178 param->email = NULL;
179 param->emaillen = 0;
180 free(param->ip);
181 param->ip = NULL;
182 param->iplen = 0;
183 param->poisoned = 0;
184}
185
186X509_VERIFY_PARAM *
187X509_VERIFY_PARAM_new(void)
188{
189 X509_VERIFY_PARAM *param;
190
191 param = calloc(1, sizeof(X509_VERIFY_PARAM));
192 if (param == NULL)
193 return NULL;
194 x509_verify_param_zero(param);
195 return param;
196}
197LCRYPTO_ALIAS(X509_VERIFY_PARAM_new);
198
199void
200X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
201{
202 if (param == NULL)
203 return;
204 x509_verify_param_zero(param);
205 free(param);
206}
207LCRYPTO_ALIAS(X509_VERIFY_PARAM_free);
208
209/*
210 * This function determines how parameters are "inherited" from one structure
211 * to another. There are several different ways this can happen.
212 *
213 * 1. If a child structure needs to have its values initialized from a parent
214 * they are simply copied across. For example SSL_CTX copied to SSL.
215 * 2. If the structure should take on values only if they are currently unset.
216 * For example the values in an SSL structure will take appropriate value
217 * for SSL servers or clients but only if the application has not set new
218 * ones.
219 *
220 * The "inh_flags" field determines how this function behaves.
221 *
222 * Normally any values which are set in the default are not copied from the
223 * destination and verify flags are ORed together.
224 *
225 * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
226 * to the destination. Effectively the values in "to" become default values
227 * which will be used only if nothing new is set in "from".
228 *
229 * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
230 * they are set or not. Flags is still Ored though.
231 *
232 * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
233 * of ORed.
234 *
235 * If X509_VP_FLAG_LOCKED is set then no values are copied.
236 *
237 * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
238 * after the next call.
239 */
240
241/* Macro to test if a field should be copied from src to dest */
242#define test_x509_verify_param_copy(field, def) \
243 (to_overwrite || \
244 ((src->field != def) && (to_default || (dest->field == def))))
245
246/* Macro to test and copy a field if necessary */
247#define x509_verify_param_copy(field, def) \
248 if (test_x509_verify_param_copy(field, def)) \
249 dest->field = src->field
250
251int
252X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src)
253{
254 unsigned long inh_flags;
255 int to_default, to_overwrite;
256
257 if (!src)
258 return 1;
259 inh_flags = dest->inh_flags | src->inh_flags;
260
261 if (inh_flags & X509_VP_FLAG_ONCE)
262 dest->inh_flags = 0;
263
264 if (inh_flags & X509_VP_FLAG_LOCKED)
265 return 1;
266
267 if (inh_flags & X509_VP_FLAG_DEFAULT)
268 to_default = 1;
269 else
270 to_default = 0;
271
272 if (inh_flags & X509_VP_FLAG_OVERWRITE)
273 to_overwrite = 1;
274 else
275 to_overwrite = 0;
276
277 x509_verify_param_copy(purpose, 0);
278 x509_verify_param_copy(trust, 0);
279 x509_verify_param_copy(depth, -1);
280
281 /* If overwrite or check time not set, copy across */
282
283 if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
284 dest->check_time = src->check_time;
285 dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
286 /* Don't need to copy flag: that is done below */
287 }
288
289 if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
290 dest->flags = 0;
291
292 dest->flags |= src->flags;
293
294 if (test_x509_verify_param_copy(policies, NULL)) {
295 if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
296 return 0;
297 }
298
299 x509_verify_param_copy(hostflags, 0);
300
301 if (test_x509_verify_param_copy(hosts, NULL)) {
302 if (dest->hosts) {
303 sk_OPENSSL_STRING_pop_free(dest->hosts, str_free);
304 dest->hosts = NULL;
305 }
306 if (src->hosts) {
307 dest->hosts = sk_OPENSSL_STRING_deep_copy(src->hosts);
308 if (dest->hosts == NULL)
309 return 0;
310 }
311 }
312
313 if (test_x509_verify_param_copy(email, NULL)) {
314 if (!X509_VERIFY_PARAM_set1_email(dest, src->email,
315 src->emaillen))
316 return 0;
317 }
318
319 if (test_x509_verify_param_copy(ip, NULL)) {
320 if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen))
321 return 0;
322 }
323
324 return 1;
325}
326LCRYPTO_ALIAS(X509_VERIFY_PARAM_inherit);
327
328int
329X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from)
330{
331 unsigned long save_flags = to->inh_flags;
332 int ret;
333
334 to->inh_flags |= X509_VP_FLAG_DEFAULT;
335 ret = X509_VERIFY_PARAM_inherit(to, from);
336 to->inh_flags = save_flags;
337 return ret;
338}
339LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1);
340
341static int
342x509_param_set1_internal(char **pdest, size_t *pdestlen, const char *src,
343 size_t srclen, int nonul)
344{
345 char *tmp;
346
347 if (src == NULL)
348 return 0;
349
350 if (srclen == 0) {
351 srclen = strlen(src);
352 if (srclen == 0)
353 return 0;
354 if ((tmp = strdup(src)) == NULL)
355 return 0;
356 } else {
357 if (nonul && memchr(src, '\0', srclen))
358 return 0;
359 if ((tmp = malloc(srclen)) == NULL)
360 return 0;
361 memcpy(tmp, src, srclen);
362 }
363
364 if (*pdest)
365 free(*pdest);
366 *pdest = tmp;
367 if (pdestlen)
368 *pdestlen = srclen;
369 return 1;
370}
371
372int
373X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
374{
375 free(param->name);
376 param->name = NULL;
377 if (name == NULL)
378 return 1;
379 param->name = strdup(name);
380 if (param->name)
381 return 1;
382 return 0;
383}
384LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_name);
385
386int
387X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
388{
389 param->flags |= flags;
390 return 1;
391}
392LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_flags);
393
394int
395X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
396{
397 param->flags &= ~flags;
398 return 1;
399}
400LCRYPTO_ALIAS(X509_VERIFY_PARAM_clear_flags);
401
402unsigned long
403X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
404{
405 return param->flags;
406}
407LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_flags);
408
409int
410X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
411{
412 if (purpose < X509_PURPOSE_MIN || purpose > X509_PURPOSE_MAX) {
413 X509V3error(X509V3_R_INVALID_PURPOSE);
414 return 0;
415 }
416
417 param->purpose = purpose;
418 return 1;
419}
420LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_purpose);
421
422int
423X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
424{
425 if (trust < X509_TRUST_MIN || trust > X509_TRUST_MAX) {
426 X509error(X509_R_INVALID_TRUST);
427 return 0;
428 }
429
430 param->trust = trust;
431 return 1;
432}
433LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_trust);
434
435void
436X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
437{
438 param->depth = depth;
439}
440LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_depth);
441
442void
443X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
444{
445 param->security_level = auth_level;
446}
447LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_auth_level);
448
449time_t
450X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param)
451{
452 return param->check_time;
453}
454LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_time);
455
456void
457X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
458{
459 param->check_time = t;
460 param->flags |= X509_V_FLAG_USE_CHECK_TIME;
461}
462LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_time);
463
464int
465X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy)
466{
467 if (param->policies == NULL)
468 param->policies = sk_ASN1_OBJECT_new_null();
469 if (param->policies == NULL)
470 return 0;
471 if (sk_ASN1_OBJECT_push(param->policies, policy) <= 0)
472 return 0;
473 return 1;
474}
475LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_policy);
476
477static STACK_OF(ASN1_OBJECT) *
478sk_ASN1_OBJECT_deep_copy(const STACK_OF(ASN1_OBJECT) *sk)
479{
480 STACK_OF(ASN1_OBJECT) *objs;
481 ASN1_OBJECT *obj = NULL;
482 int i;
483
484 if ((objs = sk_ASN1_OBJECT_new_null()) == NULL)
485 goto err;
486
487 for (i = 0; i < sk_ASN1_OBJECT_num(sk); i++) {
488 if ((obj = OBJ_dup(sk_ASN1_OBJECT_value(sk, i))) == NULL)
489 goto err;
490 if (sk_ASN1_OBJECT_push(objs, obj) <= 0)
491 goto err;
492 obj = NULL;
493 }
494
495 return objs;
496
497 err:
498 sk_ASN1_OBJECT_pop_free(objs, ASN1_OBJECT_free);
499 ASN1_OBJECT_free(obj);
500
501 return NULL;
502}
503
504int
505X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
506 STACK_OF(ASN1_OBJECT) *policies)
507{
508 if (param == NULL)
509 return 0;
510
511 sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
512 param->policies = NULL;
513
514 if (policies == NULL)
515 return 1;
516
517 if ((param->policies = sk_ASN1_OBJECT_deep_copy(policies)) == NULL)
518 return 0;
519
520 return 1;
521}
522LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_policies);
523
524int
525X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
526 const char *name, size_t namelen)
527{
528 if (x509_param_set_hosts_internal(param, SET_HOST, name, namelen))
529 return 1;
530 param->poisoned = 1;
531 return 0;
532}
533LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_host);
534
535int
536X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
537 const char *name, size_t namelen)
538{
539 if (x509_param_set_hosts_internal(param, ADD_HOST, name, namelen))
540 return 1;
541 param->poisoned = 1;
542 return 0;
543}
544LCRYPTO_ALIAS(X509_VERIFY_PARAM_add1_host);
545
546/* Public API in OpenSSL - nothing seems to use this. */
547unsigned int
548X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param)
549{
550 return param->hostflags;
551}
552
553void
554X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags)
555{
556 param->hostflags = flags;
557}
558LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_hostflags);
559
560char *
561X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
562{
563 return param->peername;
564}
565LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_peername);
566
567int
568X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
569 size_t emaillen)
570{
571 if (x509_param_set1_internal(&param->email, &param->emaillen,
572 email, emaillen, 1))
573 return 1;
574 param->poisoned = 1;
575 return 0;
576}
577LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_email);
578
579int
580X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
581 size_t iplen)
582{
583 if (iplen != 4 && iplen != 16)
584 goto err;
585 if (x509_param_set1_internal((char **)&param->ip, &param->iplen,
586 (char *)ip, iplen, 0))
587 return 1;
588 err:
589 param->poisoned = 1;
590 return 0;
591}
592LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip);
593
594int
595X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
596{
597 unsigned char ipout[16];
598 size_t iplen;
599
600 iplen = (size_t)a2i_ipadd(ipout, ipasc);
601 return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
602}
603LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip_asc);
604
605int
606X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
607{
608 return param->depth;
609}
610LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_depth);
611
612const char *
613X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
614{
615 return param->name;
616}
617LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_name);
618
619/*
620 * Default verify parameters: these are used for various applications and can
621 * be overridden by the user specified table.
622 */
623
624static const X509_VERIFY_PARAM default_table[] = {
625 {
626 .name = "default",
627 .flags = X509_V_FLAG_TRUSTED_FIRST,
628 .depth = 100,
629 .trust = 0, /* XXX This is not the default trust value */
630 },
631 {
632 .name = "pkcs7",
633 .purpose = X509_PURPOSE_SMIME_SIGN,
634 .trust = X509_TRUST_EMAIL,
635 .depth = -1,
636 },
637 {
638 .name = "smime_sign",
639 .purpose = X509_PURPOSE_SMIME_SIGN,
640 .trust = X509_TRUST_EMAIL,
641 .depth = -1,
642 },
643 {
644 .name = "ssl_client",
645 .purpose = X509_PURPOSE_SSL_CLIENT,
646 .trust = X509_TRUST_SSL_CLIENT,
647 .depth = -1,
648 },
649 {
650 .name = "ssl_server",
651 .purpose = X509_PURPOSE_SSL_SERVER,
652 .trust = X509_TRUST_SSL_SERVER,
653 .depth = -1,
654 }
655};
656
657#define N_DEFAULT_VERIFY_PARAMS (sizeof(default_table) / sizeof(default_table[0]))
658
659static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
660
661static int
662param_cmp(const X509_VERIFY_PARAM * const *a,
663 const X509_VERIFY_PARAM * const *b)
664{
665 return strcmp((*a)->name, (*b)->name);
666}
667
668int
669X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
670{
671 X509_VERIFY_PARAM *ptmp;
672 int idx;
673
674 if (param_table == NULL)
675 param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
676 if (param_table == NULL)
677 return 0;
678
679 if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param)) != -1) {
680 ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
681 X509_VERIFY_PARAM_free(ptmp);
682 (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
683 }
684
685 return sk_X509_VERIFY_PARAM_push(param_table, param) > 0;
686}
687LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_table);
688
689int
690X509_VERIFY_PARAM_get_count(void)
691{
692 int num = N_DEFAULT_VERIFY_PARAMS;
693
694 if (param_table != NULL)
695 num += sk_X509_VERIFY_PARAM_num(param_table);
696
697 return num;
698}
699LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_count);
700
701const X509_VERIFY_PARAM *
702X509_VERIFY_PARAM_get0(int id)
703{
704 int num = N_DEFAULT_VERIFY_PARAMS;
705
706 if (id < 0)
707 return NULL;
708
709 if (id < num)
710 return &default_table[id];
711
712 return sk_X509_VERIFY_PARAM_value(param_table, id - num);
713}
714LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0);
715
716const X509_VERIFY_PARAM *
717X509_VERIFY_PARAM_lookup(const char *name)
718{
719 X509_VERIFY_PARAM param;
720 size_t i;
721 int idx;
722
723 memset(&param, 0, sizeof(param));
724 param.name = (char *)name;
725 if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &param)) != -1)
726 return sk_X509_VERIFY_PARAM_value(param_table, idx);
727
728 for (i = 0; i < N_DEFAULT_VERIFY_PARAMS; i++) {
729 if (strcmp(default_table[i].name, name) == 0)
730 return &default_table[i];
731 }
732
733 return NULL;
734}
735LCRYPTO_ALIAS(X509_VERIFY_PARAM_lookup);
736
737void
738X509_VERIFY_PARAM_table_cleanup(void)
739{
740 sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
741 param_table = NULL;
742}
743LCRYPTO_ALIAS(X509_VERIFY_PARAM_table_cleanup);
diff --git a/src/lib/libcrypto/x509/x509cset.c b/src/lib/libcrypto/x509/x509cset.c
deleted file mode 100644
index 468831266f..0000000000
--- a/src/lib/libcrypto/x509/x509cset.c
+++ /dev/null
@@ -1,238 +0,0 @@
1/* $OpenBSD: x509cset.c,v 1.22 2024/03/26 23:41:45 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 2001 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 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/evp.h>
63#include <openssl/objects.h>
64#include <openssl/x509.h>
65
66#include "x509_local.h"
67
68int
69X509_CRL_up_ref(X509_CRL *x)
70{
71 return CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL) > 1;
72}
73LCRYPTO_ALIAS(X509_CRL_up_ref);
74
75int
76X509_CRL_set_version(X509_CRL *x, long version)
77{
78 if (x == NULL)
79 return 0;
80 /*
81 * RFC 5280, 4.1: versions 1 - 3 are specified as follows.
82 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
83 * The only specified versions for CRLs are 1 and 2.
84 */
85 if (version < 0 || version > 1)
86 return 0;
87 if (x->crl->version == NULL) {
88 if ((x->crl->version = ASN1_INTEGER_new()) == NULL)
89 return 0;
90 }
91 return ASN1_INTEGER_set(x->crl->version, version);
92}
93LCRYPTO_ALIAS(X509_CRL_set_version);
94
95int
96X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
97{
98 if (x == NULL || x->crl == NULL)
99 return 0;
100 return X509_NAME_set(&x->crl->issuer, name);
101}
102LCRYPTO_ALIAS(X509_CRL_set_issuer_name);
103
104int
105X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
106{
107 ASN1_TIME *in;
108
109 if (x == NULL)
110 return 0;
111 in = x->crl->lastUpdate;
112 if (in != tm) {
113 in = ASN1_STRING_dup(tm);
114 if (in != NULL) {
115 ASN1_TIME_free(x->crl->lastUpdate);
116 x->crl->lastUpdate = in;
117 }
118 }
119 return in != NULL;
120}
121LCRYPTO_ALIAS(X509_CRL_set_lastUpdate);
122
123int
124X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
125{
126 return X509_CRL_set_lastUpdate(x, tm);
127}
128LCRYPTO_ALIAS(X509_CRL_set1_lastUpdate);
129
130int
131X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
132{
133 ASN1_TIME *in;
134
135 if (x == NULL)
136 return 0;
137 in = x->crl->nextUpdate;
138 if (in != tm) {
139 in = ASN1_STRING_dup(tm);
140 if (in != NULL) {
141 ASN1_TIME_free(x->crl->nextUpdate);
142 x->crl->nextUpdate = in;
143 }
144 }
145 return in != NULL;
146}
147LCRYPTO_ALIAS(X509_CRL_set_nextUpdate);
148
149int
150X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
151{
152 return X509_CRL_set_nextUpdate(x, tm);
153}
154LCRYPTO_ALIAS(X509_CRL_set1_nextUpdate);
155
156int
157X509_CRL_sort(X509_CRL *c)
158{
159 X509_REVOKED *r;
160 int i;
161
162 /* Sort the data so it will be written in serial number order */
163 sk_X509_REVOKED_sort(c->crl->revoked);
164 for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) {
165 r = sk_X509_REVOKED_value(c->crl->revoked, i);
166 r->sequence = i;
167 }
168 c->crl->enc.modified = 1;
169 return 1;
170}
171LCRYPTO_ALIAS(X509_CRL_sort);
172
173const STACK_OF(X509_EXTENSION) *
174X509_REVOKED_get0_extensions(const X509_REVOKED *x)
175{
176 return x->extensions;
177}
178LCRYPTO_ALIAS(X509_REVOKED_get0_extensions);
179
180const ASN1_TIME *
181X509_REVOKED_get0_revocationDate(const X509_REVOKED *x)
182{
183 return x->revocationDate;
184}
185LCRYPTO_ALIAS(X509_REVOKED_get0_revocationDate);
186
187const ASN1_INTEGER *
188X509_REVOKED_get0_serialNumber(const X509_REVOKED *x)
189{
190 return x->serialNumber;
191}
192LCRYPTO_ALIAS(X509_REVOKED_get0_serialNumber);
193
194int
195X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
196{
197 ASN1_TIME *in;
198
199 if (x == NULL)
200 return 0;
201 in = x->revocationDate;
202 if (in != tm) {
203 in = ASN1_STRING_dup(tm);
204 if (in != NULL) {
205 ASN1_TIME_free(x->revocationDate);
206 x->revocationDate = in;
207 }
208 }
209 return in != NULL;
210}
211LCRYPTO_ALIAS(X509_REVOKED_set_revocationDate);
212
213int
214X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
215{
216 ASN1_INTEGER *in;
217
218 if (x == NULL)
219 return 0;
220 in = x->serialNumber;
221 if (in != serial) {
222 in = ASN1_INTEGER_dup(serial);
223 if (in != NULL) {
224 ASN1_INTEGER_free(x->serialNumber);
225 x->serialNumber = in;
226 }
227 }
228 return in != NULL;
229}
230LCRYPTO_ALIAS(X509_REVOKED_set_serialNumber);
231
232int
233i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **pp)
234{
235 crl->crl->enc.modified = 1;
236 return i2d_X509_CRL_INFO(crl->crl, pp);
237}
238LCRYPTO_ALIAS(i2d_re_X509_CRL_tbs);
diff --git a/src/lib/libcrypto/x509/x509name.c b/src/lib/libcrypto/x509/x509name.c
deleted file mode 100644
index d2df06ccc6..0000000000
--- a/src/lib/libcrypto/x509/x509name.c
+++ /dev/null
@@ -1,452 +0,0 @@
1/* $OpenBSD: x509name.c,v 1.35 2023/05/29 11:54:50 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/asn1.h>
63#include <openssl/err.h>
64#include <openssl/evp.h>
65#include <openssl/objects.h>
66#include <openssl/stack.h>
67#include <openssl/x509.h>
68
69#include "bytestring.h"
70#include "x509_local.h"
71
72int
73X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
74{
75 ASN1_OBJECT *obj;
76
77 obj = OBJ_nid2obj(nid);
78 if (obj == NULL)
79 return (-1);
80 return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
81}
82LCRYPTO_ALIAS(X509_NAME_get_text_by_NID);
83
84int
85X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
86 int len)
87{
88 unsigned char *text = NULL;
89 ASN1_STRING *data;
90 int i, text_len;
91 int ret = -1;
92 CBS cbs;
93
94 i = X509_NAME_get_index_by_OBJ(name, obj, -1);
95 if (i < 0)
96 goto err;
97 data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
98 /*
99 * Fail if we cannot encode as UTF-8, or if the UTF-8 encoding of the
100 * string contains a 0 byte, because mortal callers seldom handle the
101 * length difference correctly.
102 */
103 if ((text_len = ASN1_STRING_to_UTF8(&text, data)) < 0)
104 goto err;
105 CBS_init(&cbs, text, text_len);
106 if (CBS_contains_zero_byte(&cbs))
107 goto err;
108 /* We still support the "pass NULL to find out how much" API */
109 if (buf != NULL) {
110 if (len <= 0 || !CBS_write_bytes(&cbs, buf, len - 1, NULL))
111 goto err;
112 /* It must be a C string */
113 buf[text_len] = '\0';
114 }
115 ret = text_len;
116
117 err:
118 free(text);
119 return (ret);
120}
121LCRYPTO_ALIAS(X509_NAME_get_text_by_OBJ);
122
123int
124X509_NAME_entry_count(const X509_NAME *name)
125{
126 if (name == NULL)
127 return (0);
128 return (sk_X509_NAME_ENTRY_num(name->entries));
129}
130LCRYPTO_ALIAS(X509_NAME_entry_count);
131
132int
133X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos)
134{
135 ASN1_OBJECT *obj;
136
137 obj = OBJ_nid2obj(nid);
138 if (obj == NULL)
139 return (-2);
140 return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
141}
142LCRYPTO_ALIAS(X509_NAME_get_index_by_NID);
143
144/* NOTE: you should be passing -1, not 0 as lastpos */
145int
146X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj,
147 int lastpos)
148{
149 int n;
150 X509_NAME_ENTRY *ne;
151 STACK_OF(X509_NAME_ENTRY) *sk;
152
153 if (name == NULL)
154 return (-1);
155 if (lastpos < 0)
156 lastpos = -1;
157 sk = name->entries;
158 n = sk_X509_NAME_ENTRY_num(sk);
159 for (lastpos++; lastpos < n; lastpos++) {
160 ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
161 if (OBJ_cmp(ne->object, obj) == 0)
162 return (lastpos);
163 }
164 return (-1);
165}
166LCRYPTO_ALIAS(X509_NAME_get_index_by_OBJ);
167
168X509_NAME_ENTRY *
169X509_NAME_get_entry(const X509_NAME *name, int loc)
170{
171 if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc ||
172 loc < 0)
173 return (NULL);
174 else
175 return (sk_X509_NAME_ENTRY_value(name->entries, loc));
176}
177LCRYPTO_ALIAS(X509_NAME_get_entry);
178
179X509_NAME_ENTRY *
180X509_NAME_delete_entry(X509_NAME *name, int loc)
181{
182 X509_NAME_ENTRY *ret;
183 int i, n, set_prev, set_next;
184 STACK_OF(X509_NAME_ENTRY) *sk;
185
186 if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc ||
187 loc < 0)
188 return (NULL);
189 sk = name->entries;
190 ret = sk_X509_NAME_ENTRY_delete(sk, loc);
191 n = sk_X509_NAME_ENTRY_num(sk);
192 name->modified = 1;
193 if (loc == n)
194 return (ret);
195
196 /* else we need to fixup the set field */
197 if (loc != 0)
198 set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set;
199 else
200 set_prev = ret->set - 1;
201 set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
202
203 /* set_prev is the previous set
204 * set is the current set
205 * set_next is the following
206 * prev 1 1 1 1 1 1 1 1
207 * set 1 1 2 2
208 * next 1 1 2 2 2 2 3 2
209 * so basically only if prev and next differ by 2, then
210 * re-number down by 1 */
211 if (set_prev + 1 < set_next)
212 for (i = loc; i < n; i++)
213 sk_X509_NAME_ENTRY_value(sk, i)->set--;
214 return (ret);
215}
216LCRYPTO_ALIAS(X509_NAME_delete_entry);
217
218int
219X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
220 const unsigned char *bytes, int len, int loc, int set)
221{
222 X509_NAME_ENTRY *ne;
223 int ret;
224
225 ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
226 if (!ne)
227 return 0;
228 ret = X509_NAME_add_entry(name, ne, loc, set);
229 X509_NAME_ENTRY_free(ne);
230 return ret;
231}
232LCRYPTO_ALIAS(X509_NAME_add_entry_by_OBJ);
233
234int
235X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
236 const unsigned char *bytes, int len, int loc, int set)
237{
238 X509_NAME_ENTRY *ne;
239 int ret;
240
241 ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
242 if (!ne)
243 return 0;
244 ret = X509_NAME_add_entry(name, ne, loc, set);
245 X509_NAME_ENTRY_free(ne);
246 return ret;
247}
248LCRYPTO_ALIAS(X509_NAME_add_entry_by_NID);
249
250int
251X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
252 const unsigned char *bytes, int len, int loc, int set)
253{
254 X509_NAME_ENTRY *ne;
255 int ret;
256
257 ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
258 if (!ne)
259 return 0;
260 ret = X509_NAME_add_entry(name, ne, loc, set);
261 X509_NAME_ENTRY_free(ne);
262 return ret;
263}
264LCRYPTO_ALIAS(X509_NAME_add_entry_by_txt);
265
266/* if set is -1, append to previous set, 0 'a new one', and 1,
267 * prepend to the guy we are about to stomp on. */
268int
269X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc,
270 int set)
271{
272 X509_NAME_ENTRY *new_name = NULL;
273 int n, i, inc;
274 STACK_OF(X509_NAME_ENTRY) *sk;
275
276 if (name == NULL)
277 return (0);
278 sk = name->entries;
279 n = sk_X509_NAME_ENTRY_num(sk);
280 if (loc > n)
281 loc = n;
282 else if (loc < 0)
283 loc = n;
284 inc = (set == 0);
285 name->modified = 1;
286
287 if (set == -1) {
288 if (loc == 0) {
289 set = 0;
290 inc = 1;
291 } else
292 set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
293 } else /* if (set >= 0) */ {
294 if (loc >= n) {
295 if (loc != 0)
296 set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
297 else
298 set = 0;
299 } else
300 set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
301 }
302
303 /* OpenSSL has ASN1-generated X509_NAME_ENTRY_dup() without const. */
304 if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL)
305 goto err;
306 new_name->set = set;
307 if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
308 X509error(ERR_R_MALLOC_FAILURE);
309 goto err;
310 }
311 if (inc) {
312 n = sk_X509_NAME_ENTRY_num(sk);
313 for (i = loc + 1; i < n; i++)
314 sk_X509_NAME_ENTRY_value(sk, i)->set += 1;
315 }
316 return (1);
317
318err:
319 if (new_name != NULL)
320 X509_NAME_ENTRY_free(new_name);
321 return (0);
322}
323LCRYPTO_ALIAS(X509_NAME_add_entry);
324
325X509_NAME_ENTRY *
326X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
327 const char *field, int type, const unsigned char *bytes, int len)
328{
329 ASN1_OBJECT *obj;
330 X509_NAME_ENTRY *nentry;
331
332 obj = OBJ_txt2obj(field, 0);
333 if (obj == NULL) {
334 X509error(X509_R_INVALID_FIELD_NAME);
335 ERR_asprintf_error_data("name=%s", field);
336 return (NULL);
337 }
338 nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
339 ASN1_OBJECT_free(obj);
340 return nentry;
341}
342LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_txt);
343
344X509_NAME_ENTRY *
345X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,
346 const unsigned char *bytes, int len)
347{
348 ASN1_OBJECT *obj;
349 X509_NAME_ENTRY *nentry;
350
351 obj = OBJ_nid2obj(nid);
352 if (obj == NULL) {
353 X509error(X509_R_UNKNOWN_NID);
354 return (NULL);
355 }
356 nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
357 ASN1_OBJECT_free(obj);
358 return nentry;
359}
360LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_NID);
361
362X509_NAME_ENTRY *
363X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, const ASN1_OBJECT *obj,
364 int type, const unsigned char *bytes, int len)
365{
366 X509_NAME_ENTRY *ret;
367
368 if ((ne == NULL) || (*ne == NULL)) {
369 if ((ret = X509_NAME_ENTRY_new()) == NULL)
370 return (NULL);
371 } else
372 ret= *ne;
373
374 if (!X509_NAME_ENTRY_set_object(ret, obj))
375 goto err;
376 if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len))
377 goto err;
378
379 if ((ne != NULL) && (*ne == NULL))
380 *ne = ret;
381 return (ret);
382
383err:
384 if ((ne == NULL) || (ret != *ne))
385 X509_NAME_ENTRY_free(ret);
386 return (NULL);
387}
388LCRYPTO_ALIAS(X509_NAME_ENTRY_create_by_OBJ);
389
390int
391X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
392{
393 if ((ne == NULL) || (obj == NULL)) {
394 X509error(ERR_R_PASSED_NULL_PARAMETER);
395 return (0);
396 }
397 ASN1_OBJECT_free(ne->object);
398 ne->object = OBJ_dup(obj);
399 return ((ne->object == NULL) ? 0 : 1);
400}
401LCRYPTO_ALIAS(X509_NAME_ENTRY_set_object);
402
403int
404X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
405 const unsigned char *bytes, int len)
406{
407 int i;
408
409 if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
410 return (0);
411 if ((type > 0) && (type & MBSTRING_FLAG))
412 return ASN1_STRING_set_by_NID(&ne->value, bytes, len, type,
413 OBJ_obj2nid(ne->object)) ? 1 : 0;
414 if (len < 0)
415 len = strlen((const char *)bytes);
416 i = ASN1_STRING_set(ne->value, bytes, len);
417 if (!i)
418 return (0);
419 if (type != V_ASN1_UNDEF) {
420 if (type == V_ASN1_APP_CHOOSE)
421 ne->value->type = ASN1_PRINTABLE_type(bytes, len);
422 else
423 ne->value->type = type;
424 }
425 return (1);
426}
427LCRYPTO_ALIAS(X509_NAME_ENTRY_set_data);
428
429ASN1_OBJECT *
430X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne)
431{
432 if (ne == NULL)
433 return (NULL);
434 return (ne->object);
435}
436LCRYPTO_ALIAS(X509_NAME_ENTRY_get_object);
437
438ASN1_STRING *
439X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne)
440{
441 if (ne == NULL)
442 return (NULL);
443 return (ne->value);
444}
445LCRYPTO_ALIAS(X509_NAME_ENTRY_get_data);
446
447int
448X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)
449{
450 return (ne->set);
451}
452LCRYPTO_ALIAS(X509_NAME_ENTRY_set);
diff --git a/src/lib/libcrypto/x509/x509rset.c b/src/lib/libcrypto/x509/x509rset.c
deleted file mode 100644
index 2e2d4abd08..0000000000
--- a/src/lib/libcrypto/x509/x509rset.c
+++ /dev/null
@@ -1,113 +0,0 @@
1/* $OpenBSD: x509rset.c,v 1.16 2024/03/26 23:45:05 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/evp.h>
63#include <openssl/objects.h>
64#include <openssl/x509.h>
65
66#include "x509_local.h"
67
68int
69X509_REQ_set_version(X509_REQ *x, long version)
70{
71 if (x == NULL)
72 return 0;
73 /* RFC 2986 section 4.1 only specifies version 1, encoded as a 0. */
74 if (version != 0)
75 return 0;
76 x->req_info->enc.modified = 1;
77 return ASN1_INTEGER_set(x->req_info->version, version);
78}
79LCRYPTO_ALIAS(X509_REQ_set_version);
80
81long
82X509_REQ_get_version(const X509_REQ *x)
83{
84 return ASN1_INTEGER_get(x->req_info->version);
85}
86LCRYPTO_ALIAS(X509_REQ_get_version);
87
88int
89X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
90{
91 if (x == NULL || x->req_info == NULL)
92 return 0;
93 x->req_info->enc.modified = 1;
94 return X509_NAME_set(&x->req_info->subject, name);
95}
96LCRYPTO_ALIAS(X509_REQ_set_subject_name);
97
98X509_NAME *
99X509_REQ_get_subject_name(const X509_REQ *x)
100{
101 return x->req_info->subject;
102}
103LCRYPTO_ALIAS(X509_REQ_get_subject_name);
104
105int
106X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
107{
108 if (x == NULL || x->req_info == NULL)
109 return 0;
110 x->req_info->enc.modified = 1;
111 return X509_PUBKEY_set(&x->req_info->pubkey, pkey);
112}
113LCRYPTO_ALIAS(X509_REQ_set_pubkey);
diff --git a/src/lib/libcrypto/x509/x509spki.c b/src/lib/libcrypto/x509/x509spki.c
deleted file mode 100644
index 04c9a6f01b..0000000000
--- a/src/lib/libcrypto/x509/x509spki.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/* $OpenBSD: x509spki.c,v 1.16 2023/02/16 08:38:17 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999 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 */
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include <openssl/err.h>
64#include <openssl/x509.h>
65
66int
67NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
68{
69 if ((x == NULL) || (x->spkac == NULL))
70 return (0);
71 return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey));
72}
73LCRYPTO_ALIAS(NETSCAPE_SPKI_set_pubkey);
74
75EVP_PKEY *
76NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
77{
78 if ((x == NULL) || (x->spkac == NULL))
79 return (NULL);
80 return (X509_PUBKEY_get(x->spkac->pubkey));
81}
82LCRYPTO_ALIAS(NETSCAPE_SPKI_get_pubkey);
83
84/* Load a Netscape SPKI from a base64 encoded string */
85
86NETSCAPE_SPKI *
87NETSCAPE_SPKI_b64_decode(const char *str, int len)
88{
89 unsigned char *spki_der;
90 const unsigned char *p;
91 int spki_len;
92 NETSCAPE_SPKI *spki;
93
94 if (len <= 0)
95 len = strlen(str);
96 if (!(spki_der = malloc(len + 1))) {
97 X509error(ERR_R_MALLOC_FAILURE);
98 return NULL;
99 }
100 spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len);
101 if (spki_len < 0) {
102 X509error(X509_R_BASE64_DECODE_ERROR);
103 free(spki_der);
104 return NULL;
105 }
106 p = spki_der;
107 spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
108 free(spki_der);
109 return spki;
110}
111LCRYPTO_ALIAS(NETSCAPE_SPKI_b64_decode);
112
113/* Generate a base64 encoded string from an SPKI */
114
115char *
116NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
117{
118 unsigned char *der_spki, *p;
119 char *b64_str;
120 int der_len;
121 der_len = i2d_NETSCAPE_SPKI(spki, NULL);
122 der_spki = malloc(der_len);
123 b64_str = reallocarray(NULL, der_len, 2);
124 if (!der_spki || !b64_str) {
125 X509error(ERR_R_MALLOC_FAILURE);
126 free(der_spki);
127 free(b64_str);
128 return NULL;
129 }
130 p = der_spki;
131 i2d_NETSCAPE_SPKI(spki, &p);
132 EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
133 free(der_spki);
134 return b64_str;
135}
136LCRYPTO_ALIAS(NETSCAPE_SPKI_b64_encode);
diff --git a/src/lib/libcrypto/x509/x509type.c b/src/lib/libcrypto/x509/x509type.c
deleted file mode 100644
index 1698d8a0ab..0000000000
--- a/src/lib/libcrypto/x509/x509type.c
+++ /dev/null
@@ -1,136 +0,0 @@
1/* $OpenBSD: x509type.c,v 1.24 2023/11/13 16:16:14 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/evp.h>
62#include <openssl/objects.h>
63#include <openssl/x509.h>
64
65#include "evp_local.h"
66#include "x509_local.h"
67
68int
69X509_certificate_type(const X509 *x, const EVP_PKEY *pkey)
70{
71 const EVP_PKEY *pk = pkey;
72 int nid;
73 int ret = 0;
74
75 if (x == NULL)
76 goto done;
77
78 if (pk == NULL)
79 pk = X509_get0_pubkey(x);
80 if (pk == NULL)
81 goto done;
82
83 switch (pk->type) {
84 case EVP_PKEY_RSA:
85 ret = EVP_PK_RSA|EVP_PKT_SIGN|EVP_PKT_ENC;
86 break;
87 case EVP_PKEY_RSA_PSS:
88 ret = EVP_PK_RSA|EVP_PKT_SIGN;
89 break;
90 case EVP_PKEY_DSA:
91 ret = EVP_PK_DSA|EVP_PKT_SIGN;
92 break;
93 case EVP_PKEY_EC:
94 ret = EVP_PK_EC|EVP_PKT_SIGN|EVP_PKT_EXCH;
95 break;
96 case EVP_PKEY_ED25519:
97 ret = EVP_PKT_SIGN;
98 break;
99 case EVP_PKEY_DH:
100 ret = EVP_PK_DH|EVP_PKT_EXCH;
101 break;
102 case NID_id_GostR3410_94:
103 case NID_id_GostR3410_2001:
104 ret = EVP_PKT_EXCH|EVP_PKT_SIGN;
105 break;
106 default:
107 break;
108 }
109
110 if ((nid = X509_get_signature_nid(x)) == NID_undef)
111 goto done;
112
113 if (!OBJ_find_sigid_algs(nid, NULL, &nid))
114 goto done;
115
116 switch (nid) {
117 case NID_rsaEncryption:
118 case NID_rsa:
119 ret |= EVP_PKS_RSA;
120 break;
121 case NID_dsa:
122 case NID_dsa_2:
123 ret |= EVP_PKS_DSA;
124 break;
125 case NID_X9_62_id_ecPublicKey:
126 ret |= EVP_PKS_EC;
127 break;
128 default:
129 break;
130 }
131
132 done:
133
134 return ret;
135}
136LCRYPTO_ALIAS(X509_certificate_type);
diff --git a/src/lib/libcrypto/x509/x509v3.h b/src/lib/libcrypto/x509/x509v3.h
deleted file mode 100644
index fa31279280..0000000000
--- a/src/lib/libcrypto/x509/x509v3.h
+++ /dev/null
@@ -1,1041 +0,0 @@
1/* $OpenBSD: x509v3.h,v 1.40 2024/12/23 09:57:23 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-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 */
58#ifndef HEADER_X509V3_H
59#define HEADER_X509V3_H
60
61#include <openssl/opensslconf.h>
62
63#include <openssl/bio.h>
64#include <openssl/x509.h>
65#include <openssl/conf.h>
66
67#ifdef __cplusplus
68extern "C" {
69#endif
70
71/* Forward reference */
72struct v3_ext_method;
73struct v3_ext_ctx;
74
75/* Useful typedefs */
76
77typedef void * (*X509V3_EXT_NEW)(void);
78typedef void (*X509V3_EXT_FREE)(void *);
79typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long);
80typedef int (*X509V3_EXT_I2D)(void *, unsigned char **);
81typedef STACK_OF(CONF_VALUE) *
82 (*X509V3_EXT_I2V)(const struct v3_ext_method *method, void *ext,
83 STACK_OF(CONF_VALUE) *extlist);
84typedef void * (*X509V3_EXT_V2I)(const struct v3_ext_method *method,
85 struct v3_ext_ctx *ctx,
86 STACK_OF(CONF_VALUE) *values);
87typedef char * (*X509V3_EXT_I2S)(const struct v3_ext_method *method, void *ext);
88typedef void * (*X509V3_EXT_S2I)(const struct v3_ext_method *method,
89 struct v3_ext_ctx *ctx, const char *str);
90typedef int (*X509V3_EXT_I2R)(const struct v3_ext_method *method, void *ext,
91 BIO *out, int indent);
92typedef void * (*X509V3_EXT_R2I)(const struct v3_ext_method *method,
93 struct v3_ext_ctx *ctx, const char *str);
94
95/* V3 extension structure */
96
97struct v3_ext_method {
98 int ext_nid;
99 int ext_flags;
100 /* If this is set the following four fields are ignored */
101 ASN1_ITEM_EXP *it;
102 /* Old style ASN1 calls */
103 X509V3_EXT_NEW ext_new;
104 X509V3_EXT_FREE ext_free;
105 X509V3_EXT_D2I d2i;
106 X509V3_EXT_I2D i2d;
107
108 /* The following pair is used for string extensions */
109 X509V3_EXT_I2S i2s;
110 X509V3_EXT_S2I s2i;
111
112 /* The following pair is used for multi-valued extensions */
113 X509V3_EXT_I2V i2v;
114 X509V3_EXT_V2I v2i;
115
116 /* The following are used for raw extensions */
117 X509V3_EXT_I2R i2r;
118 X509V3_EXT_R2I r2i;
119
120 const void *usr_data; /* Any extension specific data */
121};
122
123struct v3_ext_ctx {
124 #define CTX_TEST 0x1
125 int flags;
126 X509 *issuer_cert;
127 X509 *subject_cert;
128 X509_REQ *subject_req;
129 X509_CRL *crl;
130 void *db;
131};
132
133typedef struct v3_ext_method X509V3_EXT_METHOD;
134
135DECLARE_STACK_OF(X509V3_EXT_METHOD)
136
137/* XXX - can this be made internal? */
138#define X509V3_EXT_MULTILINE 0x4
139
140/* XXX - remove it anyway? */
141/* Guess who uses this... Yes, of course, it's xca. */
142typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
143
144typedef struct BASIC_CONSTRAINTS_st {
145 int ca;
146 ASN1_INTEGER *pathlen;
147} BASIC_CONSTRAINTS;
148
149
150typedef struct PKEY_USAGE_PERIOD_st {
151 ASN1_GENERALIZEDTIME *notBefore;
152 ASN1_GENERALIZEDTIME *notAfter;
153} PKEY_USAGE_PERIOD;
154
155typedef struct otherName_st {
156 ASN1_OBJECT *type_id;
157 ASN1_TYPE *value;
158} OTHERNAME;
159
160typedef struct EDIPartyName_st {
161 ASN1_STRING *nameAssigner;
162 ASN1_STRING *partyName;
163} EDIPARTYNAME;
164
165typedef struct GENERAL_NAME_st {
166
167 #define GEN_OTHERNAME 0
168 #define GEN_EMAIL 1
169 #define GEN_DNS 2
170 #define GEN_X400 3
171 #define GEN_DIRNAME 4
172 #define GEN_EDIPARTY 5
173 #define GEN_URI 6
174 #define GEN_IPADD 7
175 #define GEN_RID 8
176
177 int type;
178 union {
179 char *ptr;
180 OTHERNAME *otherName; /* otherName */
181 ASN1_IA5STRING *rfc822Name;
182 ASN1_IA5STRING *dNSName;
183 ASN1_STRING *x400Address;
184 X509_NAME *directoryName;
185 EDIPARTYNAME *ediPartyName;
186 ASN1_IA5STRING *uniformResourceIdentifier;
187 ASN1_OCTET_STRING *iPAddress;
188 ASN1_OBJECT *registeredID;
189
190 /* Old names */
191 ASN1_OCTET_STRING *ip; /* iPAddress */
192 X509_NAME *dirn; /* dirn */
193 ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, uniformResourceIdentifier */
194 ASN1_OBJECT *rid; /* registeredID */
195 } d;
196} GENERAL_NAME;
197
198typedef struct ACCESS_DESCRIPTION_st {
199 ASN1_OBJECT *method;
200 GENERAL_NAME *location;
201} ACCESS_DESCRIPTION;
202
203typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
204
205typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;
206
207DECLARE_STACK_OF(GENERAL_NAME)
208
209typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
210DECLARE_STACK_OF(GENERAL_NAMES)
211
212DECLARE_STACK_OF(ACCESS_DESCRIPTION)
213
214typedef struct DIST_POINT_NAME_st {
215 int type;
216 union {
217 GENERAL_NAMES *fullname;
218 STACK_OF(X509_NAME_ENTRY) *relativename;
219 } name;
220 /* If relativename then this contains the full distribution point name */
221 X509_NAME *dpname;
222} DIST_POINT_NAME;
223/* All existing reasons */
224#define CRLDP_ALL_REASONS 0x807f
225
226#define CRL_REASON_NONE -1
227#define CRL_REASON_UNSPECIFIED 0
228#define CRL_REASON_KEY_COMPROMISE 1
229#define CRL_REASON_CA_COMPROMISE 2
230#define CRL_REASON_AFFILIATION_CHANGED 3
231#define CRL_REASON_SUPERSEDED 4
232#define CRL_REASON_CESSATION_OF_OPERATION 5
233#define CRL_REASON_CERTIFICATE_HOLD 6
234#define CRL_REASON_REMOVE_FROM_CRL 8
235#define CRL_REASON_PRIVILEGE_WITHDRAWN 9
236#define CRL_REASON_AA_COMPROMISE 10
237
238struct DIST_POINT_st {
239 DIST_POINT_NAME *distpoint;
240 ASN1_BIT_STRING *reasons;
241 GENERAL_NAMES *CRLissuer;
242 int dp_reasons;
243};
244
245typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
246
247DECLARE_STACK_OF(DIST_POINT)
248
249struct AUTHORITY_KEYID_st {
250 ASN1_OCTET_STRING *keyid;
251 GENERAL_NAMES *issuer;
252 ASN1_INTEGER *serial;
253};
254
255typedef struct NOTICEREF_st {
256 ASN1_STRING *organization;
257 STACK_OF(ASN1_INTEGER) *noticenos;
258} NOTICEREF;
259
260typedef struct USERNOTICE_st {
261 NOTICEREF *noticeref;
262 ASN1_STRING *exptext;
263} USERNOTICE;
264
265typedef struct POLICYQUALINFO_st {
266 ASN1_OBJECT *pqualid;
267 union {
268 ASN1_IA5STRING *cpsuri;
269 USERNOTICE *usernotice;
270 ASN1_TYPE *other;
271 } d;
272} POLICYQUALINFO;
273
274DECLARE_STACK_OF(POLICYQUALINFO)
275
276typedef struct POLICYINFO_st {
277 ASN1_OBJECT *policyid;
278 STACK_OF(POLICYQUALINFO) *qualifiers;
279} POLICYINFO;
280
281typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
282
283DECLARE_STACK_OF(POLICYINFO)
284
285typedef struct POLICY_MAPPING_st {
286 ASN1_OBJECT *issuerDomainPolicy;
287 ASN1_OBJECT *subjectDomainPolicy;
288} POLICY_MAPPING;
289
290DECLARE_STACK_OF(POLICY_MAPPING)
291
292typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;
293
294typedef struct GENERAL_SUBTREE_st {
295 GENERAL_NAME *base;
296 ASN1_INTEGER *minimum;
297 ASN1_INTEGER *maximum;
298} GENERAL_SUBTREE;
299
300DECLARE_STACK_OF(GENERAL_SUBTREE)
301
302struct NAME_CONSTRAINTS_st {
303 STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
304 STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
305};
306
307typedef struct POLICY_CONSTRAINTS_st {
308 ASN1_INTEGER *requireExplicitPolicy;
309 ASN1_INTEGER *inhibitPolicyMapping;
310} POLICY_CONSTRAINTS;
311
312struct ISSUING_DIST_POINT_st {
313 DIST_POINT_NAME *distpoint;
314 int onlyuser;
315 int onlyCA;
316 ASN1_BIT_STRING *onlysomereasons;
317 int indirectCRL;
318 int onlyattr;
319};
320
321/* Values in idp_flags field */
322/* IDP present */
323#define IDP_PRESENT 0x1
324/* IDP values inconsistent */
325#define IDP_INVALID 0x2
326/* onlyuser true */
327#define IDP_ONLYUSER 0x4
328/* onlyCA true */
329#define IDP_ONLYCA 0x8
330/* onlyattr true */
331#define IDP_ONLYATTR 0x10
332/* indirectCRL true */
333#define IDP_INDIRECT 0x20
334/* onlysomereasons present */
335#define IDP_REASONS 0x40
336
337#define X509V3_conf_err(val) ERR_asprintf_error_data( \
338 "section:%s,name:%s,value:%s", val->section, \
339 val->name, val->value);
340
341#define X509V3_set_ctx_test(ctx) \
342 X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
343#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;
344
345/* X509_PURPOSE stuff */
346
347#define EXFLAG_BCONS 0x0001
348#define EXFLAG_KUSAGE 0x0002
349#define EXFLAG_XKUSAGE 0x0004
350#define EXFLAG_NSCERT 0x0008
351
352#define EXFLAG_CA 0x0010
353#define EXFLAG_SI 0x0020 /* Self issued. */
354#define EXFLAG_V1 0x0040
355#define EXFLAG_INVALID 0x0080
356#define EXFLAG_SET 0x0100
357#define EXFLAG_CRITICAL 0x0200
358#if !defined(LIBRESSL_INTERNAL)
359#define EXFLAG_PROXY 0x0400
360#endif
361#define EXFLAG_INVALID_POLICY 0x0800
362#define EXFLAG_FRESHEST 0x1000
363#define EXFLAG_SS 0x2000 /* Self signed. */
364
365#define KU_DIGITAL_SIGNATURE 0x0080
366#define KU_NON_REPUDIATION 0x0040
367#define KU_KEY_ENCIPHERMENT 0x0020
368#define KU_DATA_ENCIPHERMENT 0x0010
369#define KU_KEY_AGREEMENT 0x0008
370#define KU_KEY_CERT_SIGN 0x0004
371#define KU_CRL_SIGN 0x0002
372#define KU_ENCIPHER_ONLY 0x0001
373#define KU_DECIPHER_ONLY 0x8000
374
375#define NS_SSL_CLIENT 0x80
376#define NS_SSL_SERVER 0x40
377#define NS_SMIME 0x20
378#define NS_OBJSIGN 0x10
379#define NS_SSL_CA 0x04
380#define NS_SMIME_CA 0x02
381#define NS_OBJSIGN_CA 0x01
382#define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)
383
384#define XKU_SSL_SERVER 0x1
385#define XKU_SSL_CLIENT 0x2
386#define XKU_SMIME 0x4
387#define XKU_CODE_SIGN 0x8
388#define XKU_SGC 0x10
389#define XKU_OCSP_SIGN 0x20
390#define XKU_TIMESTAMP 0x40
391#define XKU_DVCS 0x80
392#define XKU_ANYEKU 0x100
393
394#define X509_PURPOSE_DYNAMIC 0x1
395#define X509_PURPOSE_DYNAMIC_NAME 0x2
396
397typedef struct x509_purpose_st X509_PURPOSE;
398
399#define X509_PURPOSE_SSL_CLIENT 1
400#define X509_PURPOSE_SSL_SERVER 2
401#define X509_PURPOSE_NS_SSL_SERVER 3
402#define X509_PURPOSE_SMIME_SIGN 4
403#define X509_PURPOSE_SMIME_ENCRYPT 5
404#define X509_PURPOSE_CRL_SIGN 6
405#define X509_PURPOSE_ANY 7
406#define X509_PURPOSE_OCSP_HELPER 8
407#define X509_PURPOSE_TIMESTAMP_SIGN 9
408
409#define X509_PURPOSE_MIN 1
410#define X509_PURPOSE_MAX 9
411
412/* Flags for X509V3_EXT_print() */
413
414#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16)
415/* Return error for unknown extensions */
416#define X509V3_EXT_DEFAULT 0
417/* Print error for unknown extensions */
418#define X509V3_EXT_ERROR_UNKNOWN (1L << 16)
419/* ASN1 parse unknown extensions */
420#define X509V3_EXT_PARSE_UNKNOWN (2L << 16)
421/* BIO_dump unknown extensions */
422#define X509V3_EXT_DUMP_UNKNOWN (3L << 16)
423
424/* Flags for X509V3_add1_i2d */
425
426#define X509V3_ADD_OP_MASK 0xfL
427#define X509V3_ADD_DEFAULT 0L
428#define X509V3_ADD_APPEND 1L
429#define X509V3_ADD_REPLACE 2L
430#define X509V3_ADD_REPLACE_EXISTING 3L
431#define X509V3_ADD_KEEP_EXISTING 4L
432#define X509V3_ADD_DELETE 5L
433#define X509V3_ADD_SILENT 0x10
434
435DECLARE_STACK_OF(X509_PURPOSE)
436
437BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new(void);
438void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a);
439BASIC_CONSTRAINTS *d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, const unsigned char **in, long len);
440int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **out);
441extern const ASN1_ITEM BASIC_CONSTRAINTS_it;
442
443AUTHORITY_KEYID *AUTHORITY_KEYID_new(void);
444void AUTHORITY_KEYID_free(AUTHORITY_KEYID *a);
445AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, const unsigned char **in, long len);
446int i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **out);
447extern const ASN1_ITEM AUTHORITY_KEYID_it;
448
449PKEY_USAGE_PERIOD *PKEY_USAGE_PERIOD_new(void);
450void PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a);
451PKEY_USAGE_PERIOD *d2i_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD **a, const unsigned char **in, long len);
452int i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **out);
453extern const ASN1_ITEM PKEY_USAGE_PERIOD_it;
454
455GENERAL_NAME *GENERAL_NAME_new(void);
456void GENERAL_NAME_free(GENERAL_NAME *a);
457GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len);
458int i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out);
459extern const ASN1_ITEM GENERAL_NAME_it;
460GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
461int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
462
463
464
465ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
466 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
467STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
468 ASN1_BIT_STRING *bits,
469 STACK_OF(CONF_VALUE) *extlist);
470
471STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret);
472int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
473
474GENERAL_NAMES *GENERAL_NAMES_new(void);
475void GENERAL_NAMES_free(GENERAL_NAMES *a);
476GENERAL_NAMES *d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len);
477int i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out);
478extern const ASN1_ITEM GENERAL_NAMES_it;
479
480STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
481 GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
482GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
483 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
484
485OTHERNAME *OTHERNAME_new(void);
486void OTHERNAME_free(OTHERNAME *a);
487OTHERNAME *d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len);
488int i2d_OTHERNAME(OTHERNAME *a, unsigned char **out);
489extern const ASN1_ITEM OTHERNAME_it;
490EDIPARTYNAME *EDIPARTYNAME_new(void);
491void EDIPARTYNAME_free(EDIPARTYNAME *a);
492EDIPARTYNAME *d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len);
493int i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out);
494extern const ASN1_ITEM EDIPARTYNAME_it;
495int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
496void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
497void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
498int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
499 ASN1_OBJECT *oid, ASN1_TYPE *value);
500int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
501 ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
502
503char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
504 const ASN1_OCTET_STRING *ia5);
505ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
506 X509V3_CTX *ctx, const char *str);
507
508EXTENDED_KEY_USAGE *EXTENDED_KEY_USAGE_new(void);
509void EXTENDED_KEY_USAGE_free(EXTENDED_KEY_USAGE *a);
510EXTENDED_KEY_USAGE *d2i_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE **a, const unsigned char **in, long len);
511int i2d_EXTENDED_KEY_USAGE(EXTENDED_KEY_USAGE *a, unsigned char **out);
512extern const ASN1_ITEM EXTENDED_KEY_USAGE_it;
513int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION* a);
514
515CERTIFICATEPOLICIES *CERTIFICATEPOLICIES_new(void);
516void CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a);
517CERTIFICATEPOLICIES *d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len);
518int i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out);
519extern const ASN1_ITEM CERTIFICATEPOLICIES_it;
520POLICYINFO *POLICYINFO_new(void);
521void POLICYINFO_free(POLICYINFO *a);
522POLICYINFO *d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len);
523int i2d_POLICYINFO(POLICYINFO *a, unsigned char **out);
524extern const ASN1_ITEM POLICYINFO_it;
525POLICYQUALINFO *POLICYQUALINFO_new(void);
526void POLICYQUALINFO_free(POLICYQUALINFO *a);
527POLICYQUALINFO *d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len);
528int i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out);
529extern const ASN1_ITEM POLICYQUALINFO_it;
530USERNOTICE *USERNOTICE_new(void);
531void USERNOTICE_free(USERNOTICE *a);
532USERNOTICE *d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len);
533int i2d_USERNOTICE(USERNOTICE *a, unsigned char **out);
534extern const ASN1_ITEM USERNOTICE_it;
535NOTICEREF *NOTICEREF_new(void);
536void NOTICEREF_free(NOTICEREF *a);
537NOTICEREF *d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len);
538int i2d_NOTICEREF(NOTICEREF *a, unsigned char **out);
539extern const ASN1_ITEM NOTICEREF_it;
540
541CRL_DIST_POINTS *CRL_DIST_POINTS_new(void);
542void CRL_DIST_POINTS_free(CRL_DIST_POINTS *a);
543CRL_DIST_POINTS *d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **a, const unsigned char **in, long len);
544int i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *a, unsigned char **out);
545extern const ASN1_ITEM CRL_DIST_POINTS_it;
546DIST_POINT *DIST_POINT_new(void);
547void DIST_POINT_free(DIST_POINT *a);
548DIST_POINT *d2i_DIST_POINT(DIST_POINT **a, const unsigned char **in, long len);
549int i2d_DIST_POINT(DIST_POINT *a, unsigned char **out);
550extern const ASN1_ITEM DIST_POINT_it;
551DIST_POINT_NAME *DIST_POINT_NAME_new(void);
552void DIST_POINT_NAME_free(DIST_POINT_NAME *a);
553DIST_POINT_NAME *d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, const unsigned char **in, long len);
554int i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **out);
555extern const ASN1_ITEM DIST_POINT_NAME_it;
556ISSUING_DIST_POINT *ISSUING_DIST_POINT_new(void);
557void ISSUING_DIST_POINT_free(ISSUING_DIST_POINT *a);
558ISSUING_DIST_POINT *d2i_ISSUING_DIST_POINT(ISSUING_DIST_POINT **a, const unsigned char **in, long len);
559int i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *a, unsigned char **out);
560extern const ASN1_ITEM ISSUING_DIST_POINT_it;
561
562int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
563
564int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
565
566ACCESS_DESCRIPTION *ACCESS_DESCRIPTION_new(void);
567void ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a);
568ACCESS_DESCRIPTION *d2i_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION **a, const unsigned char **in, long len);
569int i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **out);
570extern const ASN1_ITEM ACCESS_DESCRIPTION_it;
571AUTHORITY_INFO_ACCESS *AUTHORITY_INFO_ACCESS_new(void);
572void AUTHORITY_INFO_ACCESS_free(AUTHORITY_INFO_ACCESS *a);
573AUTHORITY_INFO_ACCESS *d2i_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS **a, const unsigned char **in, long len);
574int i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *a, unsigned char **out);
575extern const ASN1_ITEM AUTHORITY_INFO_ACCESS_it;
576
577extern const ASN1_ITEM POLICY_MAPPING_it;
578POLICY_MAPPING *POLICY_MAPPING_new(void);
579void POLICY_MAPPING_free(POLICY_MAPPING *a);
580extern const ASN1_ITEM POLICY_MAPPINGS_it;
581
582extern const ASN1_ITEM GENERAL_SUBTREE_it;
583GENERAL_SUBTREE *GENERAL_SUBTREE_new(void);
584void GENERAL_SUBTREE_free(GENERAL_SUBTREE *a);
585
586extern const ASN1_ITEM NAME_CONSTRAINTS_it;
587NAME_CONSTRAINTS *NAME_CONSTRAINTS_new(void);
588void NAME_CONSTRAINTS_free(NAME_CONSTRAINTS *a);
589
590POLICY_CONSTRAINTS *POLICY_CONSTRAINTS_new(void);
591void POLICY_CONSTRAINTS_free(POLICY_CONSTRAINTS *a);
592extern const ASN1_ITEM POLICY_CONSTRAINTS_it;
593
594GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
595 const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
596 int gen_type, const char *value, int is_nc);
597
598#ifdef HEADER_CONF_H
599GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
600 CONF_VALUE *cnf);
601GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
602 const X509V3_EXT_METHOD *method,
603 X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
604void X509V3_conf_free(CONF_VALUE *val);
605
606X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
607 const char *value);
608X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name,
609 const char *value);
610int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
611 STACK_OF(X509_EXTENSION) **sk);
612int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
613 X509 *cert);
614int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
615 X509_REQ *req);
616int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
617 X509_CRL *crl);
618
619X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
620 int ext_nid, const char *value);
621X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
622 const char *name, const char *value);
623
624void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
625#endif
626
627void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
628 X509_REQ *req, X509_CRL *crl, int flags);
629
630char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint);
631ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const char *value);
632char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint);
633char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth,
634 const ASN1_ENUMERATED *aint);
635
636const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
637const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
638int X509V3_add_standard_extensions(void);
639STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
640void *X509V3_EXT_d2i(X509_EXTENSION *ext);
641void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
642 int *idx);
643
644X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
645int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
646
647char *hex_to_string(const unsigned char *buffer, long len);
648unsigned char *string_to_hex(const char *str, long *len);
649
650void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
651 int ml);
652int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent);
653int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
654
655int X509V3_extensions_print(BIO *out, const char *title,
656 const STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent);
657
658int X509_check_ca(X509 *x);
659int X509_check_purpose(X509 *x, int id, int ca);
660int X509_supported_extension(X509_EXTENSION *ex);
661int X509_check_issued(X509 *issuer, X509 *subject);
662int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
663
664int X509_PURPOSE_get_count(void);
665const X509_PURPOSE *X509_PURPOSE_get0(int idx);
666int X509_PURPOSE_get_by_sname(const char *sname);
667const char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp);
668const char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp);
669int X509_PURPOSE_get_id(const X509_PURPOSE *);
670uint32_t X509_get_extension_flags(X509 *x);
671uint32_t X509_get_key_usage(X509 *x);
672uint32_t X509_get_extended_key_usage(X509 *x);
673
674STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
675STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
676void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
677STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
678
679/* Flags for X509_check_* functions */
680/* Always check subject name for host match even if subject alt names present */
681#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1
682/* Disable wildcard matching for dnsName fields and common name. */
683#define X509_CHECK_FLAG_NO_WILDCARDS 0x2
684/* Wildcards must not match a partial label. */
685#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4
686/* Allow (non-partial) wildcards to match multiple labels. */
687#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8
688/* Constraint verifier subdomain patterns to match a single labels. */
689#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10
690/* Disable checking the CN for a hostname, to support modern validation */
691#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20
692
693int X509_check_host(X509 *x, const char *chk, size_t chklen,
694 unsigned int flags, char **peername);
695int X509_check_email(X509 *x, const char *chk, size_t chklen,
696 unsigned int flags);
697int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
698 unsigned int flags);
699int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags);
700
701ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
702ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
703int a2i_ipadd(unsigned char *ipout, const char *ipasc);
704int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
705 unsigned long chtype);
706
707#ifndef OPENSSL_NO_RFC3779
708typedef struct ASRange_st {
709 ASN1_INTEGER *min;
710 ASN1_INTEGER *max;
711} ASRange;
712
713#define ASIdOrRange_id 0
714#define ASIdOrRange_range 1
715
716typedef struct ASIdOrRange_st {
717 int type;
718 union {
719 ASN1_INTEGER *id;
720 ASRange *range;
721 } u;
722} ASIdOrRange;
723
724typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
725DECLARE_STACK_OF(ASIdOrRange)
726
727#define ASIdentifierChoice_inherit 0
728#define ASIdentifierChoice_asIdsOrRanges 1
729
730typedef struct ASIdentifierChoice_st {
731 int type;
732 union {
733 ASN1_NULL *inherit;
734 ASIdOrRanges *asIdsOrRanges;
735 } u;
736} ASIdentifierChoice;
737
738typedef struct ASIdentifiers_st {
739 ASIdentifierChoice *asnum;
740 ASIdentifierChoice *rdi;
741} ASIdentifiers;
742
743ASRange *ASRange_new(void);
744void ASRange_free(ASRange *a);
745ASRange *d2i_ASRange(ASRange **a, const unsigned char **in, long len);
746int i2d_ASRange(ASRange *a, unsigned char **out);
747extern const ASN1_ITEM ASRange_it;
748
749ASIdOrRange *ASIdOrRange_new(void);
750void ASIdOrRange_free(ASIdOrRange *a);
751ASIdOrRange *d2i_ASIdOrRange(ASIdOrRange **a, const unsigned char **in,
752 long len);
753int i2d_ASIdOrRange(ASIdOrRange *a, unsigned char **out);
754extern const ASN1_ITEM ASIdOrRange_it;
755
756ASIdentifierChoice *ASIdentifierChoice_new(void);
757void ASIdentifierChoice_free(ASIdentifierChoice *a);
758ASIdentifierChoice *d2i_ASIdentifierChoice(ASIdentifierChoice **a,
759 const unsigned char **in, long len);
760int i2d_ASIdentifierChoice(ASIdentifierChoice *a, unsigned char **out);
761extern const ASN1_ITEM ASIdentifierChoice_it;
762
763ASIdentifiers *ASIdentifiers_new(void);
764void ASIdentifiers_free(ASIdentifiers *a);
765ASIdentifiers *d2i_ASIdentifiers(ASIdentifiers **a, const unsigned char **in,
766 long len);
767int i2d_ASIdentifiers(ASIdentifiers *a, unsigned char **out);
768extern const ASN1_ITEM ASIdentifiers_it;
769
770typedef struct IPAddressRange_st {
771 ASN1_BIT_STRING *min;
772 ASN1_BIT_STRING *max;
773} IPAddressRange;
774
775#define IPAddressOrRange_addressPrefix 0
776#define IPAddressOrRange_addressRange 1
777
778typedef struct IPAddressOrRange_st {
779 int type;
780 union {
781 ASN1_BIT_STRING *addressPrefix;
782 IPAddressRange *addressRange;
783 } u;
784} IPAddressOrRange;
785
786typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
787DECLARE_STACK_OF(IPAddressOrRange)
788
789#define IPAddressChoice_inherit 0
790#define IPAddressChoice_addressesOrRanges 1
791
792typedef struct IPAddressChoice_st {
793 int type;
794 union {
795 ASN1_NULL *inherit;
796 IPAddressOrRanges *addressesOrRanges;
797 } u;
798} IPAddressChoice;
799
800typedef struct IPAddressFamily_st {
801 ASN1_OCTET_STRING *addressFamily;
802 IPAddressChoice *ipAddressChoice;
803} IPAddressFamily;
804
805typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
806DECLARE_STACK_OF(IPAddressFamily)
807
808IPAddressRange *IPAddressRange_new(void);
809void IPAddressRange_free(IPAddressRange *a);
810IPAddressRange *d2i_IPAddressRange(IPAddressRange **a,
811 const unsigned char **in, long len);
812int i2d_IPAddressRange(IPAddressRange *a, unsigned char **out);
813extern const ASN1_ITEM IPAddressRange_it;
814
815IPAddressOrRange *IPAddressOrRange_new(void);
816void IPAddressOrRange_free(IPAddressOrRange *a);
817IPAddressOrRange *d2i_IPAddressOrRange(IPAddressOrRange **a,
818 const unsigned char **in, long len);
819int i2d_IPAddressOrRange(IPAddressOrRange *a, unsigned char **out);
820extern const ASN1_ITEM IPAddressOrRange_it;
821
822IPAddressChoice *IPAddressChoice_new(void);
823void IPAddressChoice_free(IPAddressChoice *a);
824IPAddressChoice *d2i_IPAddressChoice(IPAddressChoice **a,
825 const unsigned char **in, long len);
826int i2d_IPAddressChoice(IPAddressChoice *a, unsigned char **out);
827extern const ASN1_ITEM IPAddressChoice_it;
828
829IPAddressFamily *IPAddressFamily_new(void);
830void IPAddressFamily_free(IPAddressFamily *a);
831IPAddressFamily *d2i_IPAddressFamily(IPAddressFamily **a,
832 const unsigned char **in, long len);
833int i2d_IPAddressFamily(IPAddressFamily *a, unsigned char **out);
834extern const ASN1_ITEM IPAddressFamily_it;
835
836/*
837 * API tag for elements of the ASIdentifer SEQUENCE.
838 */
839#define V3_ASID_ASNUM 0
840#define V3_ASID_RDI 1
841
842/*
843 * AFI values, assigned by IANA. It'd be nice to make the AFI
844 * handling code totally generic, but there are too many little things
845 * that would need to be defined for other address families for it to
846 * be worth the trouble.
847 */
848#define IANA_AFI_IPV4 1
849#define IANA_AFI_IPV6 2
850
851/*
852 * Utilities to construct and extract values from RFC3779 extensions,
853 * since some of the encodings (particularly for IP address prefixes
854 * and ranges) are a bit tedious to work with directly.
855 */
856int X509v3_asid_add_inherit(ASIdentifiers *asid, int which);
857int X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which,
858 ASN1_INTEGER *min, ASN1_INTEGER *max);
859int X509v3_addr_add_inherit(IPAddrBlocks *addr, const unsigned afi,
860 const unsigned *safi);
861int X509v3_addr_add_prefix(IPAddrBlocks *addr, const unsigned afi,
862 const unsigned *safi, unsigned char *a, const int prefixlen);
863int X509v3_addr_add_range(IPAddrBlocks *addr, const unsigned afi,
864 const unsigned *safi, unsigned char *min, unsigned char *max);
865unsigned X509v3_addr_get_afi(const IPAddressFamily *f);
866int X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
867 unsigned char *min, unsigned char *max, const int length);
868
869/*
870 * Canonical forms.
871 */
872int X509v3_asid_is_canonical(ASIdentifiers *asid);
873int X509v3_addr_is_canonical(IPAddrBlocks *addr);
874int X509v3_asid_canonize(ASIdentifiers *asid);
875int X509v3_addr_canonize(IPAddrBlocks *addr);
876
877/*
878 * Tests for inheritance and containment.
879 */
880int X509v3_asid_inherits(ASIdentifiers *asid);
881int X509v3_addr_inherits(IPAddrBlocks *addr);
882int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
883int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);
884
885/*
886 * Check whether RFC 3779 extensions nest properly in chains.
887 */
888int X509v3_asid_validate_path(X509_STORE_CTX *);
889int X509v3_addr_validate_path(X509_STORE_CTX *);
890int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, ASIdentifiers *ext,
891 int allow_inheritance);
892int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, IPAddrBlocks *ext,
893 int allow_inheritance);
894
895#endif /* !OPENSSL_NO_RFC3779 */
896
897void ERR_load_X509V3_strings(void);
898
899/* Error codes for the X509V3 functions. */
900
901/* Function codes. */
902#define X509V3_F_A2I_GENERAL_NAME 164
903#define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161
904#define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162
905#define X509V3_F_COPY_EMAIL 122
906#define X509V3_F_COPY_ISSUER 123
907#define X509V3_F_DO_DIRNAME 144
908#define X509V3_F_DO_EXT_CONF 124
909#define X509V3_F_DO_EXT_I2D 135
910#define X509V3_F_DO_EXT_NCONF 151
911#define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148
912#define X509V3_F_GNAMES_FROM_SECTNAME 156
913#define X509V3_F_HEX_TO_STRING 111
914#define X509V3_F_I2S_ASN1_ENUMERATED 121
915#define X509V3_F_I2S_ASN1_IA5STRING 149
916#define X509V3_F_I2S_ASN1_INTEGER 120
917#define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138
918#define X509V3_F_NOTICE_SECTION 132
919#define X509V3_F_NREF_NOS 133
920#define X509V3_F_POLICY_SECTION 131
921#define X509V3_F_PROCESS_PCI_VALUE 150
922#define X509V3_F_R2I_CERTPOL 130
923#define X509V3_F_R2I_PCI 155
924#define X509V3_F_S2I_ASN1_IA5STRING 100
925#define X509V3_F_S2I_ASN1_INTEGER 108
926#define X509V3_F_S2I_ASN1_OCTET_STRING 112
927#define X509V3_F_S2I_ASN1_SKEY_ID 114
928#define X509V3_F_S2I_SKEY_ID 115
929#define X509V3_F_SET_DIST_POINT_NAME 158
930#define X509V3_F_STRING_TO_HEX 113
931#define X509V3_F_SXNET_ADD_ID_ASC 125
932#define X509V3_F_SXNET_ADD_ID_INTEGER 126
933#define X509V3_F_SXNET_ADD_ID_ULONG 127
934#define X509V3_F_SXNET_GET_ID_ASC 128
935#define X509V3_F_SXNET_GET_ID_ULONG 129
936#define X509V3_F_V2I_ASIDENTIFIERS 163
937#define X509V3_F_V2I_ASN1_BIT_STRING 101
938#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139
939#define X509V3_F_V2I_AUTHORITY_KEYID 119
940#define X509V3_F_V2I_BASIC_CONSTRAINTS 102
941#define X509V3_F_V2I_CRLD 134
942#define X509V3_F_V2I_EXTENDED_KEY_USAGE 103
943#define X509V3_F_V2I_GENERAL_NAMES 118
944#define X509V3_F_V2I_GENERAL_NAME_EX 117
945#define X509V3_F_V2I_IDP 157
946#define X509V3_F_V2I_IPADDRBLOCKS 159
947#define X509V3_F_V2I_ISSUER_ALT 153
948#define X509V3_F_V2I_NAME_CONSTRAINTS 147
949#define X509V3_F_V2I_POLICY_CONSTRAINTS 146
950#define X509V3_F_V2I_POLICY_MAPPINGS 145
951#define X509V3_F_V2I_SUBJECT_ALT 154
952#define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160
953#define X509V3_F_V3_GENERIC_EXTENSION 116
954#define X509V3_F_X509V3_ADD1_I2D 140
955#define X509V3_F_X509V3_ADD_VALUE 105
956#define X509V3_F_X509V3_EXT_ADD 104
957#define X509V3_F_X509V3_EXT_ADD_ALIAS 106
958#define X509V3_F_X509V3_EXT_CONF 107
959#define X509V3_F_X509V3_EXT_I2D 136
960#define X509V3_F_X509V3_EXT_NCONF 152
961#define X509V3_F_X509V3_GET_SECTION 142
962#define X509V3_F_X509V3_GET_STRING 143
963#define X509V3_F_X509V3_GET_VALUE_BOOL 110
964#define X509V3_F_X509V3_PARSE_LIST 109
965#define X509V3_F_X509_PURPOSE_ADD 137
966#define X509V3_F_X509_PURPOSE_SET 141
967
968/* Reason codes. */
969#define X509V3_R_BAD_IP_ADDRESS 118
970#define X509V3_R_BAD_OBJECT 119
971#define X509V3_R_BN_DEC2BN_ERROR 100
972#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101
973#define X509V3_R_DIRNAME_ERROR 149
974#define X509V3_R_DISTPOINT_ALREADY_SET 160
975#define X509V3_R_DUPLICATE_ZONE_ID 133
976#define X509V3_R_ERROR_CONVERTING_ZONE 131
977#define X509V3_R_ERROR_CREATING_EXTENSION 144
978#define X509V3_R_ERROR_IN_EXTENSION 128
979#define X509V3_R_EXPECTED_A_SECTION_NAME 137
980#define X509V3_R_EXTENSION_EXISTS 145
981#define X509V3_R_EXTENSION_NAME_ERROR 115
982#define X509V3_R_EXTENSION_NOT_FOUND 102
983#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103
984#define X509V3_R_EXTENSION_VALUE_ERROR 116
985#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151
986#define X509V3_R_ILLEGAL_HEX_DIGIT 113
987#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152
988#define X509V3_R_INVALID_MULTIPLE_RDNS 161
989#define X509V3_R_INVALID_ASNUMBER 162
990#define X509V3_R_INVALID_ASRANGE 163
991#define X509V3_R_INVALID_BOOLEAN_STRING 104
992#define X509V3_R_INVALID_EXTENSION_STRING 105
993#define X509V3_R_INVALID_INHERITANCE 165
994#define X509V3_R_INVALID_IPADDRESS 166
995#define X509V3_R_INVALID_NAME 106
996#define X509V3_R_INVALID_NULL_ARGUMENT 107
997#define X509V3_R_INVALID_NULL_NAME 108
998#define X509V3_R_INVALID_NULL_VALUE 109
999#define X509V3_R_INVALID_NUMBER 140
1000#define X509V3_R_INVALID_NUMBERS 141
1001#define X509V3_R_INVALID_OBJECT_IDENTIFIER 110
1002#define X509V3_R_INVALID_OPTION 138
1003#define X509V3_R_INVALID_POLICY_IDENTIFIER 134
1004#define X509V3_R_INVALID_PROXY_POLICY_SETTING 153
1005#define X509V3_R_INVALID_PURPOSE 146
1006#define X509V3_R_INVALID_SAFI 164
1007#define X509V3_R_INVALID_SECTION 135
1008#define X509V3_R_INVALID_SYNTAX 143
1009#define X509V3_R_ISSUER_DECODE_ERROR 126
1010#define X509V3_R_MISSING_VALUE 124
1011#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142
1012#define X509V3_R_NO_CONFIG_DATABASE 136
1013#define X509V3_R_NO_ISSUER_CERTIFICATE 121
1014#define X509V3_R_NO_ISSUER_DETAILS 127
1015#define X509V3_R_NO_POLICY_IDENTIFIER 139
1016#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154
1017#define X509V3_R_NO_PUBLIC_KEY 114
1018#define X509V3_R_NO_SUBJECT_DETAILS 125
1019#define X509V3_R_ODD_NUMBER_OF_DIGITS 112
1020#define X509V3_R_OPERATION_NOT_DEFINED 148
1021#define X509V3_R_OTHERNAME_ERROR 147
1022#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155
1023#define X509V3_R_POLICY_PATH_LENGTH 156
1024#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157
1025#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158
1026#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
1027#define X509V3_R_SECTION_NOT_FOUND 150
1028#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122
1029#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123
1030#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111
1031#define X509V3_R_UNKNOWN_EXTENSION 129
1032#define X509V3_R_UNKNOWN_EXTENSION_NAME 130
1033#define X509V3_R_UNKNOWN_OPTION 120
1034#define X509V3_R_UNSUPPORTED_OPTION 117
1035#define X509V3_R_UNSUPPORTED_TYPE 167
1036#define X509V3_R_USER_TOO_LONG 132
1037
1038#ifdef __cplusplus
1039}
1040#endif
1041#endif
diff --git a/src/lib/libcrypto/x509/x_all.c b/src/lib/libcrypto/x509/x_all.c
deleted file mode 100644
index 5997714061..0000000000
--- a/src/lib/libcrypto/x509/x_all.c
+++ /dev/null
@@ -1,536 +0,0 @@
1/* $OpenBSD: x_all.c,v 1.32 2024/06/19 08:00:53 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/opensslconf.h>
62
63#include <openssl/asn1.h>
64#include <openssl/buffer.h>
65#include <openssl/evp.h>
66#include <openssl/stack.h>
67#include <openssl/x509.h>
68
69#ifndef OPENSSL_NO_DSA
70#include <openssl/dsa.h>
71#endif
72#ifndef OPENSSL_NO_RSA
73#include <openssl/rsa.h>
74#endif
75
76#include "x509_local.h"
77
78X509 *
79d2i_X509_bio(BIO *bp, X509 **x509)
80{
81 return ASN1_item_d2i_bio(&X509_it, bp, x509);
82}
83LCRYPTO_ALIAS(d2i_X509_bio);
84
85int
86i2d_X509_bio(BIO *bp, X509 *x509)
87{
88 return ASN1_item_i2d_bio(&X509_it, bp, x509);
89}
90LCRYPTO_ALIAS(i2d_X509_bio);
91
92X509 *
93d2i_X509_fp(FILE *fp, X509 **x509)
94{
95 return ASN1_item_d2i_fp(&X509_it, fp, x509);
96}
97LCRYPTO_ALIAS(d2i_X509_fp);
98
99int
100i2d_X509_fp(FILE *fp, X509 *x509)
101{
102 return ASN1_item_i2d_fp(&X509_it, fp, x509);
103}
104LCRYPTO_ALIAS(i2d_X509_fp);
105
106X509_CRL *
107d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
108{
109 return ASN1_item_d2i_bio(&X509_CRL_it, bp, crl);
110}
111LCRYPTO_ALIAS(d2i_X509_CRL_bio);
112
113int
114i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
115{
116 return ASN1_item_i2d_bio(&X509_CRL_it, bp, crl);
117}
118LCRYPTO_ALIAS(i2d_X509_CRL_bio);
119
120X509_CRL *
121d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
122{
123 return ASN1_item_d2i_fp(&X509_CRL_it, fp, crl);
124}
125LCRYPTO_ALIAS(d2i_X509_CRL_fp);
126
127int
128i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
129{
130 return ASN1_item_i2d_fp(&X509_CRL_it, fp, crl);
131}
132LCRYPTO_ALIAS(i2d_X509_CRL_fp);
133
134X509_REQ *
135d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
136{
137 return ASN1_item_d2i_bio(&X509_REQ_it, bp, req);
138}
139LCRYPTO_ALIAS(d2i_X509_REQ_bio);
140
141int
142i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
143{
144 return ASN1_item_i2d_bio(&X509_REQ_it, bp, req);
145}
146LCRYPTO_ALIAS(i2d_X509_REQ_bio);
147
148X509_REQ *
149d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
150{
151 return ASN1_item_d2i_fp(&X509_REQ_it, fp, req);
152}
153LCRYPTO_ALIAS(d2i_X509_REQ_fp);
154
155int
156i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
157{
158 return ASN1_item_i2d_fp(&X509_REQ_it, fp, req);
159}
160LCRYPTO_ALIAS(i2d_X509_REQ_fp);
161
162#ifndef OPENSSL_NO_RSA
163RSA *
164d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
165{
166 return ASN1_item_d2i_bio(&RSAPrivateKey_it, bp, rsa);
167}
168LCRYPTO_ALIAS(d2i_RSAPrivateKey_bio);
169
170int
171i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
172{
173 return ASN1_item_i2d_bio(&RSAPrivateKey_it, bp, rsa);
174}
175LCRYPTO_ALIAS(i2d_RSAPrivateKey_bio);
176
177RSA *
178d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
179{
180 return ASN1_item_d2i_fp(&RSAPrivateKey_it, fp, rsa);
181}
182LCRYPTO_ALIAS(d2i_RSAPrivateKey_fp);
183
184int
185i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
186{
187 return ASN1_item_i2d_fp(&RSAPrivateKey_it, fp, rsa);
188}
189LCRYPTO_ALIAS(i2d_RSAPrivateKey_fp);
190
191RSA *
192d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
193{
194 return ASN1_item_d2i_bio(&RSAPublicKey_it, bp, rsa);
195}
196LCRYPTO_ALIAS(d2i_RSAPublicKey_bio);
197
198int
199i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
200{
201 return ASN1_item_i2d_bio(&RSAPublicKey_it, bp, rsa);
202}
203LCRYPTO_ALIAS(i2d_RSAPublicKey_bio);
204
205RSA *
206d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
207{
208 return ASN1_item_d2i_fp(&RSAPublicKey_it, fp, rsa);
209}
210LCRYPTO_ALIAS(d2i_RSAPublicKey_fp);
211
212int
213i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
214{
215 return ASN1_item_i2d_fp(&RSAPublicKey_it, fp, rsa);
216}
217LCRYPTO_ALIAS(i2d_RSAPublicKey_fp);
218#endif
219
220#ifndef OPENSSL_NO_DSA
221DSA *
222d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
223{
224 return ASN1_item_d2i_bio(&DSAPrivateKey_it, bp, dsa);
225}
226LCRYPTO_ALIAS(d2i_DSAPrivateKey_bio);
227
228int
229i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
230{
231 return ASN1_item_i2d_bio(&DSAPrivateKey_it, bp, dsa);
232}
233LCRYPTO_ALIAS(i2d_DSAPrivateKey_bio);
234
235DSA *
236d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
237{
238 return ASN1_item_d2i_fp(&DSAPrivateKey_it, fp, dsa);
239}
240LCRYPTO_ALIAS(d2i_DSAPrivateKey_fp);
241
242int
243i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
244{
245 return ASN1_item_i2d_fp(&DSAPrivateKey_it, fp, dsa);
246}
247LCRYPTO_ALIAS(i2d_DSAPrivateKey_fp);
248#endif
249
250#ifndef OPENSSL_NO_EC
251EC_KEY *
252d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
253{
254 return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
255}
256LCRYPTO_ALIAS(d2i_ECPrivateKey_bio);
257
258int
259i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
260{
261 return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey);
262}
263LCRYPTO_ALIAS(i2d_ECPrivateKey_bio);
264
265EC_KEY *
266d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
267{
268 return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
269}
270LCRYPTO_ALIAS(d2i_ECPrivateKey_fp);
271
272int
273i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
274{
275 return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey);
276}
277LCRYPTO_ALIAS(i2d_ECPrivateKey_fp);
278#endif
279
280X509_SIG *
281d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
282{
283 return ASN1_item_d2i_bio(&X509_SIG_it, bp, p8);
284}
285LCRYPTO_ALIAS(d2i_PKCS8_bio);
286
287int
288i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
289{
290 return ASN1_item_i2d_bio(&X509_SIG_it, bp, p8);
291}
292LCRYPTO_ALIAS(i2d_PKCS8_bio);
293
294X509_SIG *
295d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
296{
297 return ASN1_item_d2i_fp(&X509_SIG_it, fp, p8);
298}
299LCRYPTO_ALIAS(d2i_PKCS8_fp);
300
301int
302i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
303{
304 return ASN1_item_i2d_fp(&X509_SIG_it, fp, p8);
305}
306LCRYPTO_ALIAS(i2d_PKCS8_fp);
307
308PKCS8_PRIV_KEY_INFO *
309d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO **p8inf)
310{
311 return ASN1_item_d2i_bio(&PKCS8_PRIV_KEY_INFO_it, bp,
312 p8inf);
313}
314LCRYPTO_ALIAS(d2i_PKCS8_PRIV_KEY_INFO_bio);
315
316int
317i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
318{
319 return ASN1_item_i2d_bio(&PKCS8_PRIV_KEY_INFO_it, bp,
320 p8inf);
321}
322LCRYPTO_ALIAS(i2d_PKCS8_PRIV_KEY_INFO_bio);
323
324PKCS8_PRIV_KEY_INFO *
325d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO **p8inf)
326{
327 return ASN1_item_d2i_fp(&PKCS8_PRIV_KEY_INFO_it, fp,
328 p8inf);
329}
330LCRYPTO_ALIAS(d2i_PKCS8_PRIV_KEY_INFO_fp);
331
332int
333i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
334{
335 return ASN1_item_i2d_fp(&PKCS8_PRIV_KEY_INFO_it, fp,
336 p8inf);
337}
338LCRYPTO_ALIAS(i2d_PKCS8_PRIV_KEY_INFO_fp);
339
340EVP_PKEY *
341d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
342{
343 return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey,
344 bp, a);
345}
346LCRYPTO_ALIAS(d2i_PrivateKey_bio);
347
348int
349i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
350{
351 return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey);
352}
353LCRYPTO_ALIAS(i2d_PrivateKey_bio);
354
355EVP_PKEY *
356d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
357{
358 return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey,
359 fp, a);
360}
361LCRYPTO_ALIAS(d2i_PrivateKey_fp);
362
363int
364i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
365{
366 return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey);
367}
368LCRYPTO_ALIAS(i2d_PrivateKey_fp);
369
370int
371i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
372{
373 PKCS8_PRIV_KEY_INFO *p8inf;
374 int ret;
375
376 p8inf = EVP_PKEY2PKCS8(key);
377 if (!p8inf)
378 return 0;
379 ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
380 PKCS8_PRIV_KEY_INFO_free(p8inf);
381 return ret;
382}
383LCRYPTO_ALIAS(i2d_PKCS8PrivateKeyInfo_bio);
384
385int
386i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
387{
388 PKCS8_PRIV_KEY_INFO *p8inf;
389 int ret;
390 p8inf = EVP_PKEY2PKCS8(key);
391 if (!p8inf)
392 return 0;
393 ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
394 PKCS8_PRIV_KEY_INFO_free(p8inf);
395 return ret;
396}
397LCRYPTO_ALIAS(i2d_PKCS8PrivateKeyInfo_fp);
398
399int
400X509_verify(X509 *a, EVP_PKEY *r)
401{
402 if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
403 return 0;
404 return ASN1_item_verify(&X509_CINF_it, a->sig_alg,
405 a->signature, a->cert_info, r);
406}
407LCRYPTO_ALIAS(X509_verify);
408
409int
410X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
411{
412 return ASN1_item_verify(&X509_REQ_INFO_it,
413 a->sig_alg, a->signature, a->req_info, r);
414}
415LCRYPTO_ALIAS(X509_REQ_verify);
416
417int
418NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
419{
420 return ASN1_item_verify(&NETSCAPE_SPKAC_it,
421 a->sig_algor, a->signature, a->spkac, r);
422}
423LCRYPTO_ALIAS(NETSCAPE_SPKI_verify);
424
425int
426X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
427{
428 x->cert_info->enc.modified = 1;
429 return ASN1_item_sign(&X509_CINF_it,
430 x->cert_info->signature, x->sig_alg, x->signature,
431 x->cert_info, pkey, md);
432}
433LCRYPTO_ALIAS(X509_sign);
434
435int
436X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
437{
438 x->cert_info->enc.modified = 1;
439 return ASN1_item_sign_ctx(&X509_CINF_it,
440 x->cert_info->signature, x->sig_alg, x->signature,
441 x->cert_info, ctx);
442}
443LCRYPTO_ALIAS(X509_sign_ctx);
444
445int
446X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
447{
448 return ASN1_item_sign(&X509_REQ_INFO_it,
449 x->sig_alg, NULL, x->signature, x->req_info, pkey, md);
450}
451LCRYPTO_ALIAS(X509_REQ_sign);
452
453int
454X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
455{
456 return ASN1_item_sign_ctx(&X509_REQ_INFO_it,
457 x->sig_alg, NULL, x->signature, x->req_info, ctx);
458}
459LCRYPTO_ALIAS(X509_REQ_sign_ctx);
460
461int
462X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
463{
464 x->crl->enc.modified = 1;
465 return ASN1_item_sign(&X509_CRL_INFO_it, x->crl->sig_alg,
466 x->sig_alg, x->signature, x->crl, pkey, md);
467}
468LCRYPTO_ALIAS(X509_CRL_sign);
469
470int
471X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
472{
473 x->crl->enc.modified = 1;
474 return ASN1_item_sign_ctx(&X509_CRL_INFO_it,
475 x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
476}
477LCRYPTO_ALIAS(X509_CRL_sign_ctx);
478
479int
480NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
481{
482 return ASN1_item_sign(&NETSCAPE_SPKAC_it,
483 x->sig_algor, NULL, x->signature, x->spkac, pkey, md);
484}
485LCRYPTO_ALIAS(NETSCAPE_SPKI_sign);
486
487int
488X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
489 unsigned int *len)
490{
491 ASN1_BIT_STRING *key;
492 key = X509_get0_pubkey_bitstr(data);
493 if (!key)
494 return 0;
495 return EVP_Digest(key->data, key->length, md, len, type, NULL);
496}
497LCRYPTO_ALIAS(X509_pubkey_digest);
498
499int
500X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
501 unsigned int *len)
502{
503 return ASN1_item_digest(&X509_it, type, (void *)data, md, len);
504}
505LCRYPTO_ALIAS(X509_digest);
506
507int
508X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md,
509 unsigned int *len)
510{
511 return ASN1_item_digest(&X509_CRL_it, type, (void *)data, md, len);
512}
513LCRYPTO_ALIAS(X509_CRL_digest);
514
515int
516X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md,
517 unsigned int *len)
518{
519 return ASN1_item_digest(&X509_REQ_it, type, (void *)data, md, len);
520}
521LCRYPTO_ALIAS(X509_REQ_digest);
522
523int
524X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md,
525 unsigned int *len)
526{
527 return ASN1_item_digest(&X509_NAME_it, type, (void *)data, md, len);
528}
529LCRYPTO_ALIAS(X509_NAME_digest);
530
531int
532X509_up_ref(X509 *x)
533{
534 return CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509) > 1;
535}
536LCRYPTO_ALIAS(X509_up_ref);