Move peer chain security checks into x509_vfy.c
[openssl.git] / crypto / x509 / x509_vpm.c
1 /*
2  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3  * 2004.
4  */
5 /* ====================================================================
6  * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58
59 #include <stdio.h>
60
61 #include "internal/cryptlib.h"
62 #include <openssl/crypto.h>
63 #include <openssl/lhash.h>
64 #include <openssl/buffer.h>
65 #include <openssl/x509.h>
66 #include <openssl/x509v3.h>
67
68 #include "x509_lcl.h"
69
70 /* X509_VERIFY_PARAM functions */
71
72 #define SET_HOST 0
73 #define ADD_HOST 1
74
75 static char *str_copy(const char *s)
76 {
77     return OPENSSL_strdup(s);
78 }
79
80 static void str_free(char *s)
81 {
82     OPENSSL_free(s);
83 }
84
85 static int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode,
86                                     const char *name, size_t namelen)
87 {
88     char *copy;
89
90     /*
91      * Refuse names with embedded NUL bytes, except perhaps as final byte.
92      * XXX: Do we need to push an error onto the error stack?
93      */
94     if (namelen == 0 || name == NULL)
95         namelen = name ? strlen(name) : 0;
96     else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen))
97         return 0;
98     if (namelen > 0 && name[namelen - 1] == '\0')
99         --namelen;
100
101     if (mode == SET_HOST) {
102         sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free);
103         vpm->hosts = NULL;
104     }
105     if (name == NULL || namelen == 0)
106         return 1;
107
108     copy = OPENSSL_strndup(name, namelen);
109     if (copy == NULL)
110         return 0;
111
112     if (vpm->hosts == NULL &&
113         (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
114         OPENSSL_free(copy);
115         return 0;
116     }
117
118     if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) {
119         OPENSSL_free(copy);
120         if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) {
121             sk_OPENSSL_STRING_free(vpm->hosts);
122             vpm->hosts = NULL;
123         }
124         return 0;
125     }
126
127     return 1;
128 }
129
130 static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
131 {
132     if (!param)
133         return;
134     param->name = NULL;
135     param->purpose = 0;
136     param->trust = X509_TRUST_DEFAULT;
137     /*
138      * param->inh_flags = X509_VP_FLAG_DEFAULT;
139      */
140     param->inh_flags = 0;
141     param->flags = 0;
142     param->depth = -1;
143     param->auth_level = -1; /* -1 means unset, 0 is explicit */
144     sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
145     param->policies = NULL;
146     sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
147     param->hosts = NULL;
148     OPENSSL_free(param->peername);
149     param->peername = NULL;
150     OPENSSL_free(param->email);
151     param->email = NULL;
152     param->emaillen = 0;
153     OPENSSL_free(param->ip);
154     param->ip = NULL;
155     param->iplen = 0;
156 }
157
158 X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
159 {
160     X509_VERIFY_PARAM *param;
161
162     param = OPENSSL_zalloc(sizeof(*param));
163     if (param == NULL)
164         return NULL;
165     x509_verify_param_zero(param);
166     return param;
167 }
168
169 void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
170 {
171     if (!param)
172         return;
173     x509_verify_param_zero(param);
174     OPENSSL_free(param);
175 }
176
177 /*-
178  * This function determines how parameters are "inherited" from one structure
179  * to another. There are several different ways this can happen.
180  *
181  * 1. If a child structure needs to have its values initialized from a parent
182  *    they are simply copied across. For example SSL_CTX copied to SSL.
183  * 2. If the structure should take on values only if they are currently unset.
184  *    For example the values in an SSL structure will take appropriate value
185  *    for SSL servers or clients but only if the application has not set new
186  *    ones.
187  *
188  * The "inh_flags" field determines how this function behaves.
189  *
190  * Normally any values which are set in the default are not copied from the
191  * destination and verify flags are ORed together.
192  *
193  * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
194  * to the destination. Effectively the values in "to" become default values
195  * which will be used only if nothing new is set in "from".
196  *
197  * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
198  * they are set or not. Flags is still Ored though.
199  *
200  * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
201  * of ORed.
202  *
203  * If X509_VP_FLAG_LOCKED is set then no values are copied.
204  *
205  * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
206  * after the next call.
207  */
208
209 /* Macro to test if a field should be copied from src to dest */
210
211 #define test_x509_verify_param_copy(field, def) \
212         (to_overwrite || \
213                 ((src->field != def) && (to_default || (dest->field == def))))
214
215 /* Macro to test and copy a field if necessary */
216
217 #define x509_verify_param_copy(field, def) \
218         if (test_x509_verify_param_copy(field, def)) \
219                 dest->field = src->field
220
221 int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
222                               const X509_VERIFY_PARAM *src)
223 {
224     unsigned long inh_flags;
225     int to_default, to_overwrite;
226     if (!src)
227         return 1;
228     inh_flags = dest->inh_flags | src->inh_flags;
229
230     if (inh_flags & X509_VP_FLAG_ONCE)
231         dest->inh_flags = 0;
232
233     if (inh_flags & X509_VP_FLAG_LOCKED)
234         return 1;
235
236     if (inh_flags & X509_VP_FLAG_DEFAULT)
237         to_default = 1;
238     else
239         to_default = 0;
240
241     if (inh_flags & X509_VP_FLAG_OVERWRITE)
242         to_overwrite = 1;
243     else
244         to_overwrite = 0;
245
246     x509_verify_param_copy(purpose, 0);
247     x509_verify_param_copy(trust, X509_TRUST_DEFAULT);
248     x509_verify_param_copy(depth, -1);
249     x509_verify_param_copy(auth_level, -1);
250
251     /* If overwrite or check time not set, copy across */
252
253     if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
254         dest->check_time = src->check_time;
255         dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
256         /* Don't need to copy flag: that is done below */
257     }
258
259     if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
260         dest->flags = 0;
261
262     dest->flags |= src->flags;
263
264     if (test_x509_verify_param_copy(policies, NULL)) {
265         if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
266             return 0;
267     }
268
269     /* Copy the host flags if and only if we're copying the host list */
270     if (test_x509_verify_param_copy(hosts, NULL)) {
271         sk_OPENSSL_STRING_pop_free(dest->hosts, str_free);
272         dest->hosts = NULL;
273         if (src->hosts) {
274             dest->hosts =
275                 sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free);
276             if (dest->hosts == NULL)
277                 return 0;
278             dest->hostflags = src->hostflags;
279         }
280     }
281
282     if (test_x509_verify_param_copy(email, NULL)) {
283         if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen))
284             return 0;
285     }
286
287     if (test_x509_verify_param_copy(ip, NULL)) {
288         if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen))
289             return 0;
290     }
291
292     return 1;
293 }
294
295 int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
296                            const X509_VERIFY_PARAM *from)
297 {
298     unsigned long save_flags = to->inh_flags;
299     int ret;
300     to->inh_flags |= X509_VP_FLAG_DEFAULT;
301     ret = X509_VERIFY_PARAM_inherit(to, from);
302     to->inh_flags = save_flags;
303     return ret;
304 }
305
306 static int int_x509_param_set1(char **pdest, size_t *pdestlen,
307                                const char *src, size_t srclen)
308 {
309     void *tmp;
310     if (src) {
311         if (srclen == 0) {
312             tmp = OPENSSL_strdup(src);
313             srclen = strlen(src);
314         } else
315             tmp = OPENSSL_memdup(src, srclen);
316         if (!tmp)
317             return 0;
318     } else {
319         tmp = NULL;
320         srclen = 0;
321     }
322     OPENSSL_free(*pdest);
323     *pdest = tmp;
324     if (pdestlen)
325         *pdestlen = srclen;
326     return 1;
327 }
328
329 int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
330 {
331     OPENSSL_free(param->name);
332     param->name = OPENSSL_strdup(name);
333     if (param->name)
334         return 1;
335     return 0;
336 }
337
338 int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
339 {
340     param->flags |= flags;
341     if (flags & X509_V_FLAG_POLICY_MASK)
342         param->flags |= X509_V_FLAG_POLICY_CHECK;
343     return 1;
344 }
345
346 int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
347                                   unsigned long flags)
348 {
349     param->flags &= ~flags;
350     return 1;
351 }
352
353 unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
354 {
355     return param->flags;
356 }
357
358 int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
359 {
360     return X509_PURPOSE_set(&param->purpose, purpose);
361 }
362
363 int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
364 {
365     return X509_TRUST_set(&param->trust, trust);
366 }
367
368 void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
369 {
370     param->depth = depth;
371 }
372
373 void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
374 {
375     param->auth_level = auth_level;
376 }
377
378 void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
379 {
380     param->check_time = t;
381     param->flags |= X509_V_FLAG_USE_CHECK_TIME;
382 }
383
384 int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
385                                   ASN1_OBJECT *policy)
386 {
387     if (!param->policies) {
388         param->policies = sk_ASN1_OBJECT_new_null();
389         if (!param->policies)
390             return 0;
391     }
392     if (!sk_ASN1_OBJECT_push(param->policies, policy))
393         return 0;
394     return 1;
395 }
396
397 int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
398                                     STACK_OF(ASN1_OBJECT) *policies)
399 {
400     int i;
401     ASN1_OBJECT *oid, *doid;
402
403     if (!param)
404         return 0;
405     sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
406
407     if (!policies) {
408         param->policies = NULL;
409         return 1;
410     }
411
412     param->policies = sk_ASN1_OBJECT_new_null();
413     if (!param->policies)
414         return 0;
415
416     for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
417         oid = sk_ASN1_OBJECT_value(policies, i);
418         doid = OBJ_dup(oid);
419         if (!doid)
420             return 0;
421         if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
422             ASN1_OBJECT_free(doid);
423             return 0;
424         }
425     }
426     param->flags |= X509_V_FLAG_POLICY_CHECK;
427     return 1;
428 }
429
430 int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
431                                 const char *name, size_t namelen)
432 {
433     return int_x509_param_set_hosts(param, SET_HOST, name, namelen);
434 }
435
436 int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
437                                 const char *name, size_t namelen)
438 {
439     return int_x509_param_set_hosts(param, ADD_HOST, name, namelen);
440 }
441
442 void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
443                                      unsigned int flags)
444 {
445     param->hostflags = flags;
446 }
447
448 char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
449 {
450     return param->peername;
451 }
452
453 /*
454  * Move peername from one param structure to another, freeing any name present
455  * at the target.  If the source is a NULL parameter structure, free and zero
456  * the target peername.
457  */
458 void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to,
459                                      X509_VERIFY_PARAM *from)
460 {
461     char *peername = (from != NULL) ? from->peername : NULL;
462
463     if (to->peername != peername) {
464         OPENSSL_free(to->peername);
465         to->peername = peername;
466     }
467     if (from)
468         from->peername = NULL;
469 }
470
471 int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
472                                  const char *email, size_t emaillen)
473 {
474     return int_x509_param_set1(&param->email, &param->emaillen,
475                                email, emaillen);
476 }
477
478 int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
479                               const unsigned char *ip, size_t iplen)
480 {
481     if (iplen != 0 && iplen != 4 && iplen != 16)
482         return 0;
483     return int_x509_param_set1((char **)&param->ip, &param->iplen,
484                                (char *)ip, iplen);
485 }
486
487 int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
488 {
489     unsigned char ipout[16];
490     size_t iplen;
491
492     iplen = (size_t)a2i_ipadd(ipout, ipasc);
493     if (iplen == 0)
494         return 0;
495     return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
496 }
497
498 int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
499 {
500     return param->depth;
501 }
502
503 int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param)
504 {
505     return param->auth_level;
506 }
507
508 const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
509 {
510     return param->name;
511 }
512
513 #define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0
514
515 /*
516  * Default verify parameters: these are used for various applications and can
517  * be overridden by the user specified table. NB: the 'name' field *must* be
518  * in alphabetical order because it will be searched using OBJ_search.
519  */
520
521 static const X509_VERIFY_PARAM default_table[] = {
522     {
523      "default",                 /* X509 default parameters */
524      0,                         /* Check time */
525      0,                         /* internal flags */
526      X509_V_FLAG_TRUSTED_FIRST, /* flags */
527      0,                         /* purpose */
528      0,                         /* trust */
529      100,                       /* depth */
530      -1,                        /* auth_level */
531      NULL,                      /* policies */
532      vpm_empty_id},
533     {
534      "pkcs7",                   /* S/MIME sign parameters */
535      0,                         /* Check time */
536      0,                         /* internal flags */
537      0,                         /* flags */
538      X509_PURPOSE_SMIME_SIGN,   /* purpose */
539      X509_TRUST_EMAIL,          /* trust */
540      -1,                        /* depth */
541      -1,                        /* auth_level */
542      NULL,                      /* policies */
543      vpm_empty_id},
544     {
545      "smime_sign",              /* S/MIME sign parameters */
546      0,                         /* Check time */
547      0,                         /* internal flags */
548      0,                         /* flags */
549      X509_PURPOSE_SMIME_SIGN,   /* purpose */
550      X509_TRUST_EMAIL,          /* trust */
551      -1,                        /* depth */
552      -1,                        /* auth_level */
553      NULL,                      /* policies */
554      vpm_empty_id},
555     {
556      "ssl_client",              /* SSL/TLS client parameters */
557      0,                         /* Check time */
558      0,                         /* internal flags */
559      0,                         /* flags */
560      X509_PURPOSE_SSL_CLIENT,   /* purpose */
561      X509_TRUST_SSL_CLIENT,     /* trust */
562      -1,                        /* depth */
563      -1,                        /* auth_level */
564      NULL,                      /* policies */
565      vpm_empty_id},
566     {
567      "ssl_server",              /* SSL/TLS server parameters */
568      0,                         /* Check time */
569      0,                         /* internal flags */
570      0,                         /* flags */
571      X509_PURPOSE_SSL_SERVER,   /* purpose */
572      X509_TRUST_SSL_SERVER,     /* trust */
573      -1,                        /* depth */
574      -1,                        /* auth_level */
575      NULL,                      /* policies */
576      vpm_empty_id}
577 };
578
579 static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
580
581 static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
582 {
583     return strcmp(a->name, b->name);
584 }
585
586 DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table);
587 IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table);
588
589 static int param_cmp(const X509_VERIFY_PARAM *const *a,
590                      const X509_VERIFY_PARAM *const *b)
591 {
592     return strcmp((*a)->name, (*b)->name);
593 }
594
595 int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
596 {
597     int idx;
598     X509_VERIFY_PARAM *ptmp;
599     if (param_table == NULL) {
600         param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
601         if (param_table == NULL)
602             return 0;
603     } else {
604         idx = sk_X509_VERIFY_PARAM_find(param_table, param);
605         if (idx != -1) {
606             ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
607             X509_VERIFY_PARAM_free(ptmp);
608             (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
609         }
610     }
611     if (!sk_X509_VERIFY_PARAM_push(param_table, param))
612         return 0;
613     return 1;
614 }
615
616 int X509_VERIFY_PARAM_get_count(void)
617 {
618     int num = OSSL_NELEM(default_table);
619     if (param_table)
620         num += sk_X509_VERIFY_PARAM_num(param_table);
621     return num;
622 }
623
624 const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
625 {
626     int num = OSSL_NELEM(default_table);
627     if (id < num)
628         return default_table + id;
629     return sk_X509_VERIFY_PARAM_value(param_table, id - num);
630 }
631
632 const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
633 {
634     int idx;
635     X509_VERIFY_PARAM pm;
636
637     pm.name = (char *)name;
638     if (param_table) {
639         idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
640         if (idx != -1)
641             return sk_X509_VERIFY_PARAM_value(param_table, idx);
642     }
643     return OBJ_bsearch_table(&pm, default_table, OSSL_NELEM(default_table));
644 }
645
646 void X509_VERIFY_PARAM_table_cleanup(void)
647 {
648     sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
649     param_table = NULL;
650 }