Coverage Report

Created: 2018-08-29 13:53

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