1 /* $OpenBSD: x509_vpm.c,v 1.45 2024/03/29 04:50:11 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
74 int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
75 size_t emaillen);
76 int 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
82 static void
str_free(char * s)83 str_free(char *s)
84 {
85 free(s);
86 }
87
STACK_OF(OPENSSL_STRING)88 static STACK_OF(OPENSSL_STRING) *
89 sk_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
115 static int
x509_param_set_hosts_internal(X509_VERIFY_PARAM * vpm,int mode,const char * name,size_t namelen)116 x509_param_set_hosts_internal(X509_VERIFY_PARAM *vpm, 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 && vpm->hosts) {
130 sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free);
131 vpm->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 (vpm->hosts == NULL &&
140 (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
141 free(copy);
142 return 0;
143 }
144
145 if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) {
146 free(copy);
147 if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) {
148 sk_OPENSSL_STRING_free(vpm->hosts);
149 vpm->hosts = NULL;
150 }
151 return 0;
152 }
153
154 return 1;
155 }
156
157 static void
x509_verify_param_zero(X509_VERIFY_PARAM * param)158 x509_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
186 X509_VERIFY_PARAM *
X509_VERIFY_PARAM_new(void)187 X509_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 }
197 LCRYPTO_ALIAS(X509_VERIFY_PARAM_new);
198
199 void
X509_VERIFY_PARAM_free(X509_VERIFY_PARAM * param)200 X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
201 {
202 if (param == NULL)
203 return;
204 x509_verify_param_zero(param);
205 free(param);
206 }
207 LCRYPTO_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
251 int
X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM * dest,const X509_VERIFY_PARAM * src)252 X509_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 }
326 LCRYPTO_ALIAS(X509_VERIFY_PARAM_inherit);
327
328 int
X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM * to,const X509_VERIFY_PARAM * from)329 X509_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 }
339 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1);
340
341 static int
x509_param_set1_internal(char ** pdest,size_t * pdestlen,const char * src,size_t srclen,int nonul)342 x509_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
372 int
X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM * param,const char * name)373 X509_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 }
384 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_name);
385
386 int
X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM * param,unsigned long flags)387 X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
388 {
389 param->flags |= flags;
390 return 1;
391 }
392 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_flags);
393
394 int
X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM * param,unsigned long flags)395 X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
396 {
397 param->flags &= ~flags;
398 return 1;
399 }
400 LCRYPTO_ALIAS(X509_VERIFY_PARAM_clear_flags);
401
402 unsigned long
X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM * param)403 X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
404 {
405 return param->flags;
406 }
407 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_flags);
408
409 int
X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM * param,int purpose)410 X509_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 }
420 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_purpose);
421
422 int
X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM * param,int trust)423 X509_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 }
433 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_trust);
434
435 void
X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM * param,int depth)436 X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
437 {
438 param->depth = depth;
439 }
440 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_depth);
441
442 void
X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM * param,int auth_level)443 X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
444 {
445 param->security_level = auth_level;
446 }
447 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_auth_level);
448
449 time_t
X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM * param)450 X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param)
451 {
452 return param->check_time;
453 }
454 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_time);
455
456 void
X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM * param,time_t t)457 X509_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 }
462 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_time);
463
464 int
X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM * param,ASN1_OBJECT * policy)465 X509_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 }
475 LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_policy);
476
STACK_OF(ASN1_OBJECT)477 static STACK_OF(ASN1_OBJECT) *
478 sk_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
504 int
X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM * param,STACK_OF (ASN1_OBJECT)* policies)505 X509_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 }
522 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_policies);
523
524 int
X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM * param,const char * name,size_t namelen)525 X509_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 }
533 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_host);
534
535 int
X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM * param,const char * name,size_t namelen)536 X509_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 }
544 LCRYPTO_ALIAS(X509_VERIFY_PARAM_add1_host);
545
546 /* Public API in OpenSSL - nothing seems to use this. */
547 unsigned int
X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM * param)548 X509_VERIFY_PARAM_get_hostflags(X509_VERIFY_PARAM *param)
549 {
550 return param->hostflags;
551 }
552
553 void
X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM * param,unsigned int flags)554 X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags)
555 {
556 param->hostflags = flags;
557 }
558 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set_hostflags);
559
560 char *
X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM * param)561 X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
562 {
563 return param->peername;
564 }
565 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0_peername);
566
567 int
X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM * param,const char * email,size_t emaillen)568 X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
569 size_t emaillen)
570 {
571 if (x509_param_set1_internal(¶m->email, ¶m->emaillen,
572 email, emaillen, 1))
573 return 1;
574 param->poisoned = 1;
575 return 0;
576 }
577 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_email);
578
579 int
X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM * param,const unsigned char * ip,size_t iplen)580 X509_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 **)¶m->ip, ¶m->iplen,
586 (char *)ip, iplen, 0))
587 return 1;
588 err:
589 param->poisoned = 1;
590 return 0;
591 }
592 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip);
593
594 int
X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM * param,const char * ipasc)595 X509_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 }
603 LCRYPTO_ALIAS(X509_VERIFY_PARAM_set1_ip_asc);
604
605 int
X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM * param)606 X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
607 {
608 return param->depth;
609 }
610 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_depth);
611
612 const char *
X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM * param)613 X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
614 {
615 return param->name;
616 }
617 LCRYPTO_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
624 static 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 static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
658
659 static int
param_cmp(const X509_VERIFY_PARAM * const * a,const X509_VERIFY_PARAM * const * b)660 param_cmp(const X509_VERIFY_PARAM * const *a,
661 const X509_VERIFY_PARAM * const *b)
662 {
663 return strcmp((*a)->name, (*b)->name);
664 }
665
666 int
X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM * param)667 X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
668 {
669 X509_VERIFY_PARAM *ptmp;
670 if (!param_table) {
671 param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
672 if (!param_table)
673 return 0;
674 } else {
675 size_t idx;
676
677 if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param))
678 != -1) {
679 ptmp = sk_X509_VERIFY_PARAM_value(param_table,
680 idx);
681 X509_VERIFY_PARAM_free(ptmp);
682 (void)sk_X509_VERIFY_PARAM_delete(param_table,
683 idx);
684 }
685 }
686 if (!sk_X509_VERIFY_PARAM_push(param_table, param))
687 return 0;
688 return 1;
689 }
690 LCRYPTO_ALIAS(X509_VERIFY_PARAM_add0_table);
691
692 int
X509_VERIFY_PARAM_get_count(void)693 X509_VERIFY_PARAM_get_count(void)
694 {
695 int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
696 if (param_table)
697 num += sk_X509_VERIFY_PARAM_num(param_table);
698 return num;
699 }
700 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get_count);
701
702 const X509_VERIFY_PARAM *
X509_VERIFY_PARAM_get0(int id)703 X509_VERIFY_PARAM_get0(int id)
704 {
705 int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
706 if (id < num)
707 return default_table + id;
708 return sk_X509_VERIFY_PARAM_value(param_table, id - num);
709 }
710 LCRYPTO_ALIAS(X509_VERIFY_PARAM_get0);
711
712 const X509_VERIFY_PARAM *
X509_VERIFY_PARAM_lookup(const char * name)713 X509_VERIFY_PARAM_lookup(const char *name)
714 {
715 X509_VERIFY_PARAM pm;
716 unsigned int i, limit;
717
718 pm.name = (char *)name;
719 if (param_table) {
720 size_t idx;
721 if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &pm)) != -1)
722 return sk_X509_VERIFY_PARAM_value(param_table, idx);
723 }
724
725 limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM);
726 for (i = 0; i < limit; i++) {
727 if (strcmp(default_table[i].name, name) == 0) {
728 return &default_table[i];
729 }
730 }
731 return NULL;
732 }
733 LCRYPTO_ALIAS(X509_VERIFY_PARAM_lookup);
734
735 void
X509_VERIFY_PARAM_table_cleanup(void)736 X509_VERIFY_PARAM_table_cleanup(void)
737 {
738 if (param_table)
739 sk_X509_VERIFY_PARAM_pop_free(param_table,
740 X509_VERIFY_PARAM_free);
741 param_table = NULL;
742 }
743 LCRYPTO_ALIAS(X509_VERIFY_PARAM_table_cleanup);
744