Coverage Report

Created: 2026-05-06 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/x509/x509_vpm.c
Line
Count
Source
1
/*
2
 * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (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
18
#include "crypto/ctype.h"
19
#include "crypto/x509.h"
20
21
#include "x509_local.h"
22
23
typedef enum {
24
    OSSL_CHARSET_NONASCII,
25
    OSSL_CHARSET_ASCII,
26
    OSSL_CHARSET_ASCII_ALNUM,
27
} ossl_charset_t;
28
29
/* X509_VERIFY_PARAM functions */
30
31
#define SET_HOST 0
32
#define ADD_HOST 1
33
34
static X509_BUFFER *buffer_from_bytes(const uint8_t *bytes, size_t length)
35
0
{
36
0
    X509_BUFFER *buf;
37
38
0
    if ((buf = OPENSSL_zalloc(sizeof *buf)) != NULL
39
0
        && (buf->data = OPENSSL_memdup(bytes, length)) != NULL) {
40
0
        buf->len = length;
41
0
    } else {
42
0
        OPENSSL_free(buf);
43
0
        buf = NULL;
44
0
    }
45
0
    return buf;
46
0
}
47
48
/*
49
 * Copies |length| bytes from |bytes| to a new buffer, making the data
50
 * A C string. It is an error for the |bytes| to contain any \0 values
51
 * within |length|. |bytes| need not itself be \0 terminated, the data
52
 * in the buffer will be on success.
53
 */
54
static X509_BUFFER *buffer_from_string(const uint8_t *bytes, size_t length)
55
0
{
56
0
    X509_BUFFER *buf, *ret = NULL;
57
0
    uint8_t *data = NULL;
58
59
0
    if ((buf = OPENSSL_zalloc(sizeof *buf)) == NULL)
60
0
        goto err;
61
62
0
    if ((data = (uint8_t *)OPENSSL_strndup((char *)bytes, length)) == NULL)
63
0
        goto err;
64
65
0
    if (strlen((char *)data) != length)
66
0
        goto err;
67
68
0
    ret = buf;
69
0
    buf = NULL;
70
0
    ret->data = data;
71
0
    ret->len = length;
72
0
    data = NULL;
73
74
0
err:
75
0
    OPENSSL_free(buf);
76
0
    OPENSSL_free(data);
77
78
0
    return ret;
79
0
}
80
81
static X509_BUFFER *buffer_copy(const X509_BUFFER *b)
82
0
{
83
0
    return buffer_from_bytes(b->data, b->len);
84
0
}
85
86
static void buffer_free(X509_BUFFER *b)
87
0
{
88
0
    if (b == NULL)
89
0
        return;
90
0
    OPENSSL_free((void *)b->data);
91
0
    OPENSSL_free(b);
92
0
}
93
94
static int replace_buffer_stack(STACK_OF(X509_BUFFER) **dest,
95
    STACK_OF(X509_BUFFER) *const *src)
96
0
{
97
0
    sk_X509_BUFFER_pop_free(*dest, buffer_free);
98
0
    *dest = NULL;
99
0
    if (*src != NULL) {
100
0
        *dest = sk_X509_BUFFER_deep_copy(*src, buffer_copy, buffer_free);
101
0
        if (*dest == NULL)
102
0
            return 0;
103
0
    }
104
0
    return 1;
105
0
}
106
107
static int buffer_cmp(const X509_BUFFER *const *a, const X509_BUFFER *const *b)
108
0
{
109
0
    if ((*a)->len < (*b)->len)
110
0
        return -1;
111
0
    if ((*a)->len > (*b)->len)
112
0
        return 1;
113
0
    if ((*b)->len == 0)
114
0
        return 0;
115
0
    return memcmp((*a)->data, (*b)->data, (*b)->len);
116
0
}
117
118
static void clear_buffer_stack(STACK_OF(X509_BUFFER) **buffer_stack)
119
0
{
120
0
    sk_X509_BUFFER_pop_free(*buffer_stack, buffer_free);
121
0
    *buffer_stack = NULL;
122
0
}
123
124
static int add_bytes_to_buffer_stack(STACK_OF(X509_BUFFER) **buffer_stack,
125
    const uint8_t *name, size_t name_len)
126
0
{
127
0
    STACK_OF(X509_BUFFER) *tmp_stack = NULL;
128
0
    X509_BUFFER *copy = NULL;
129
0
    int ret = 0;
130
131
0
    if ((copy = buffer_from_bytes(name, name_len)) == NULL)
132
0
        goto err;
133
134
0
    tmp_stack = *buffer_stack;
135
0
    if (tmp_stack == NULL && (tmp_stack = sk_X509_BUFFER_new(buffer_cmp)) == NULL)
136
0
        goto err;
137
138
0
    if (!sk_X509_BUFFER_push(tmp_stack, copy))
139
0
        goto err;
140
141
0
    ret = 1;
142
0
    copy = NULL;
143
0
    *buffer_stack = tmp_stack;
144
0
    tmp_stack = NULL;
145
146
0
err:
147
0
    sk_X509_BUFFER_pop_free(tmp_stack, buffer_free);
148
0
    buffer_free(copy);
149
150
0
    return ret;
151
0
}
152
153
static int add_string_to_buffer_stack(STACK_OF(X509_BUFFER) **buffer_stack,
154
    const uint8_t *name, size_t name_len)
155
0
{
156
0
    STACK_OF(X509_BUFFER) *tmp_stack = NULL;
157
0
    X509_BUFFER *copy = NULL;
158
0
    int ret = 0;
159
160
0
    if ((copy = buffer_from_string(name, name_len)) == NULL)
161
0
        goto err;
162
163
0
    tmp_stack = *buffer_stack;
164
0
    if (tmp_stack == NULL && (tmp_stack = sk_X509_BUFFER_new(buffer_cmp)) == NULL)
165
0
        goto err;
166
167
0
    if (!sk_X509_BUFFER_push(tmp_stack, copy))
168
0
        goto err;
169
170
0
    ret = 1;
171
0
    copy = NULL;
172
0
    *buffer_stack = tmp_stack;
173
0
    tmp_stack = NULL;
174
175
0
err:
176
0
    sk_X509_BUFFER_pop_free(tmp_stack, buffer_free);
177
0
    buffer_free(copy);
178
179
0
    return ret;
180
0
}
181
182
static int validate_string_name(const char *name, size_t *name_len)
183
0
{
184
0
    size_t len = *name_len;
185
186
0
    if (name == NULL || len == 0)
187
0
        return 0;
188
189
    /*
190
     * Accept the trailing \0 byte if this is a C string. This is to
191
     * preserver behaviour that is traditional for the
192
     * set1_[host|email] functions.
193
     */
194
0
    if (name[len - 1] == '\0')
195
0
        len--;
196
197
    /* Refuse the empty string */
198
0
    if (len == 0)
199
0
        return 0;
200
201
    /* Refuse values with embedded \0 bytes other than at the end */
202
0
    if (memchr(name, '\0', len) != NULL)
203
0
        return 0;
204
205
0
    *name_len = len;
206
0
    return 1;
207
0
}
208
209
/*
210
 * Default input validation for verification parameter names. As these
211
 * could potentially come from untrusted input, doing basic input
212
 * validation makes sense, and ensures that subsequent parsing or
213
 * comparisons do not need to handle extreme out of range input.
214
 */
215
216
/* Default ip name input validation */
217
static int validate_ip_name(const uint8_t *name, size_t len)
218
0
{
219
0
    if (name != NULL && (len == 4 || len == 16))
220
0
        return 1;
221
0
    return 0;
222
0
}
223
224
static ossl_charset_t ossl_name_charset(int c, ossl_charset_t charset)
225
0
{
226
0
    if (ossl_isalnum(c))
227
0
        return 1;
228
0
    if (ossl_isascii(c))
229
0
        return charset == OSSL_CHARSET_ASCII
230
0
            || charset == OSSL_CHARSET_NONASCII;
231
0
    return charset == OSSL_CHARSET_NONASCII;
232
0
}
233
234
static int is_label_ok(int c, ossl_charset_t charset)
235
0
{
236
0
    if (!ossl_name_charset(c, charset) && c != '_')
237
0
        return 0;
238
0
    else
239
0
        return c != '.' && c != '-';
240
0
}
241
242
/* Default host name input validation */
243
static int validate_hostname_part(const char *name, size_t len,
244
    ossl_charset_t charset)
245
0
{
246
0
    size_t i, part_len;
247
0
    char c, prev;
248
249
0
    if (len < 2 || len > 256)
250
0
        return 0;
251
252
0
    part_len = 0;
253
0
    prev = '\0';
254
0
    for (i = 0; i < len; i++) {
255
0
        c = name[i];
256
0
        if (c == '.') {
257
            /*
258
             * Can not start a label with a .
259
             * unless it is the very first character.
260
             */
261
0
            if (part_len == 0 && i != 0)
262
0
                return 0;
263
            /* Can not end a label with a - */
264
0
            if (prev == '-')
265
0
                return 0;
266
0
            part_len = 0;
267
0
        } else {
268
            /* Can not start a label with a - */
269
0
            if (part_len == 0 && c == '-') {
270
0
                return 0;
271
0
            }
272
0
            if (!is_label_ok(c, charset) && c != '-')
273
0
                return 0;
274
0
        }
275
0
        part_len++;
276
0
        if (part_len > 63)
277
0
            return 0;
278
279
0
        prev = c;
280
0
    }
281
    /* Can not end with a . or a _ */
282
0
    if (prev == '.' || prev == '-')
283
0
        return 0;
284
285
0
    return 1;
286
0
}
287
288
static int validate_local_part(const char *name, size_t len,
289
    ossl_charset_t *out_charset)
290
0
{
291
0
    ossl_charset_t charset = OSSL_CHARSET_ASCII;
292
0
    size_t i;
293
294
0
    for (i = 0; i < len; i++) {
295
0
        if (name[i] == '\0')
296
0
            return 0;
297
0
        if (!ossl_isascii(name[i]))
298
0
            charset = OSSL_CHARSET_NONASCII;
299
0
    }
300
301
0
    *out_charset = charset;
302
0
    return 1;
303
0
}
304
305
/* Default email name input validation */
306
static int validate_email_name(const char *name, size_t len, int rfc822)
307
0
{
308
0
    size_t dns_len, local_len;
309
0
    const char *at, *next, *dnsname;
310
0
    ossl_charset_t local_charset;
311
312
    /*
313
     * 64 for local part, 1 for @, 255 for domain name
314
     */
315
0
    if (len > 320)
316
0
        goto err;
317
318
    /* Reject it if there is no @ */
319
0
    if ((at = memchr(name, '@', len)) == NULL)
320
0
        goto err;
321
322
    /* Go to the last @ */
323
0
    while ((next = memchr(at + 1, '@', len - (at - name + 1))) != NULL)
324
0
        at = next;
325
326
    /* Ensure the local part is not oversize */
327
0
    local_len = len - (at - name);
328
0
    if (local_len > 64)
329
0
        goto err;
330
331
0
    if (!validate_local_part(name, len, &local_charset))
332
0
        goto err;
333
334
0
    if (rfc822 && local_charset == OSSL_CHARSET_NONASCII)
335
0
        goto err;
336
337
0
    if (!rfc822 && local_charset == OSSL_CHARSET_ASCII)
338
0
        goto err;
339
340
    /* What is after the @ must be valid as a dns name */
341
0
    dnsname = at + 1;
342
0
    dns_len = len - local_len - 1;
343
344
0
    if (rfc822)
345
0
        return validate_hostname_part(dnsname, dns_len, OSSL_CHARSET_ASCII_ALNUM);
346
347
0
    return validate_hostname_part(dnsname, dns_len, OSSL_CHARSET_NONASCII);
348
349
0
err:
350
0
    ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT);
351
0
    return 0;
352
0
}
353
354
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
355
0
{
356
0
    X509_VERIFY_PARAM *param;
357
358
0
    param = OPENSSL_zalloc(sizeof(*param));
359
0
    if (param == NULL)
360
0
        return NULL;
361
0
    param->trust = X509_TRUST_DEFAULT;
362
    /* param->inh_flags = X509_VP_FLAG_DEFAULT; */
363
0
    param->depth = -1;
364
0
    param->auth_level = -1; /* -1 means unset, 0 is explicit */
365
0
    return param;
366
0
}
367
368
void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
369
0
{
370
0
    if (param == NULL)
371
0
        return;
372
0
    sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
373
0
    clear_buffer_stack(&param->hosts);
374
0
    clear_buffer_stack(&param->ips);
375
0
    clear_buffer_stack(&param->rfc822s);
376
0
    clear_buffer_stack(&param->smtputf8s);
377
0
    OPENSSL_free(param->peername);
378
0
    OPENSSL_free(param);
379
0
}
380
381
/*-
382
 * This function determines how parameters are "inherited" from one structure
383
 * to another. There are several different ways this can happen.
384
 *
385
 * 1. If a child structure needs to have its values initialized from a parent
386
 *    they are simply copied across. For example SSL_CTX copied to SSL.
387
 * 2. If the structure should take on values only if they are currently unset.
388
 *    For example the values in an SSL structure will take appropriate value
389
 *    for SSL servers or clients but only if the application has not set new
390
 *    ones.
391
 *
392
 * The "inh_flags" field determines how this function behaves.
393
 *
394
 * Normally any values which are set in the default are not copied from the
395
 * destination and verify flags are ORed together.
396
 *
397
 * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
398
 * to the destination. Effectively the values in "to" become default values
399
 * which will be used only if nothing new is set in "from".
400
 *
401
 * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
402
 * they are set or not. Flags is still Ored though.
403
 *
404
 * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
405
 * of ORed.
406
 *
407
 * If X509_VP_FLAG_LOCKED is set then no values are copied.
408
 *
409
 * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
410
 * after the next call.
411
 */
412
413
/* Macro to test if a field should be copied from src to dest */
414
415
#define test_x509_verify_param_copy(field, def) \
416
0
    (to_overwrite || (src->field != def && (to_default || dest->field == def)))
417
418
/* Macro to test and copy a field if necessary */
419
420
#define x509_verify_param_copy(field, def)       \
421
0
    if (test_x509_verify_param_copy(field, def)) \
422
0
        dest->field = src->field;
423
424
int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
425
    const X509_VERIFY_PARAM *src)
426
0
{
427
0
    unsigned long inh_flags;
428
0
    int to_default, to_overwrite;
429
430
0
    if (src == NULL)
431
0
        return 1;
432
0
    inh_flags = dest->inh_flags | src->inh_flags;
433
434
0
    if ((inh_flags & X509_VP_FLAG_ONCE) != 0)
435
0
        dest->inh_flags = 0;
436
437
0
    if ((inh_flags & X509_VP_FLAG_LOCKED) != 0)
438
0
        return 1;
439
440
0
    to_default = (inh_flags & X509_VP_FLAG_DEFAULT) != 0;
441
0
    to_overwrite = (inh_flags & X509_VP_FLAG_OVERWRITE) != 0;
442
443
0
    x509_verify_param_copy(purpose, 0);
444
0
    x509_verify_param_copy(trust, X509_TRUST_DEFAULT);
445
0
    x509_verify_param_copy(depth, -1);
446
0
    x509_verify_param_copy(auth_level, -1);
447
448
    /* If overwrite or check time not set, copy across */
449
450
0
    if (to_overwrite || (dest->flags & X509_V_FLAG_USE_CHECK_TIME) == 0) {
451
0
        dest->check_time = src->check_time;
452
0
        dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
453
        /* Don't need to copy flag: that is done below */
454
0
    }
455
456
0
    if ((inh_flags & X509_VP_FLAG_RESET_FLAGS) != 0)
457
0
        dest->flags = 0;
458
459
0
    dest->flags |= src->flags;
460
461
0
    if (test_x509_verify_param_copy(policies, NULL)) {
462
0
        if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
463
0
            return 0;
464
0
    }
465
466
0
    x509_verify_param_copy(hostflags, 0);
467
468
0
    if (test_x509_verify_param_copy(hosts, NULL)) {
469
0
        if (!replace_buffer_stack(&dest->hosts, &src->hosts))
470
0
            return 0;
471
0
    }
472
0
    x509_verify_param_copy(validate_host, NULL);
473
474
0
    if (test_x509_verify_param_copy(ips, NULL)) {
475
0
        if (!replace_buffer_stack(&dest->ips, &src->ips))
476
0
            return 0;
477
0
    }
478
0
    x509_verify_param_copy(validate_ip, NULL);
479
480
0
    if (test_x509_verify_param_copy(rfc822s, NULL)) {
481
0
        if (!replace_buffer_stack(&dest->rfc822s, &src->rfc822s))
482
0
            return 0;
483
0
    }
484
0
    x509_verify_param_copy(validate_rfc822, NULL);
485
486
0
    if (test_x509_verify_param_copy(smtputf8s, NULL)) {
487
0
        if (!replace_buffer_stack(&dest->smtputf8s, &src->smtputf8s))
488
0
            return 0;
489
0
    }
490
0
    x509_verify_param_copy(validate_smtputf8, NULL);
491
492
0
    return 1;
493
0
}
494
495
int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
496
    const X509_VERIFY_PARAM *from)
497
0
{
498
0
    unsigned long save_flags;
499
0
    int ret;
500
501
0
    if (to == NULL) {
502
0
        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
503
0
        return 0;
504
0
    }
505
0
    save_flags = to->inh_flags;
506
0
    to->inh_flags |= X509_VP_FLAG_DEFAULT;
507
0
    ret = X509_VERIFY_PARAM_inherit(to, from);
508
0
    to->inh_flags = save_flags;
509
0
    return ret;
510
0
}
511
512
int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
513
0
{
514
0
    OPENSSL_free(param->name);
515
0
    param->name = OPENSSL_strdup(name);
516
0
    return param->name != NULL;
517
0
}
518
519
int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
520
0
{
521
0
    param->flags |= flags;
522
0
    if ((flags & X509_V_FLAG_POLICY_MASK) != 0)
523
0
        param->flags |= X509_V_FLAG_POLICY_CHECK;
524
0
    return 1;
525
0
}
526
527
int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
528
    unsigned long flags)
529
0
{
530
0
    param->flags &= ~flags;
531
0
    return 1;
532
0
}
533
534
unsigned long X509_VERIFY_PARAM_get_flags(const X509_VERIFY_PARAM *param)
535
0
{
536
0
    return param->flags;
537
0
}
538
539
uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param)
540
0
{
541
0
    return param->inh_flags;
542
0
}
543
544
int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, uint32_t flags)
545
0
{
546
0
    param->inh_flags = flags;
547
0
    return 1;
548
0
}
549
550
/* resets to default (any) purpose if |purpose| == X509_PURPOSE_DEFAULT_ANY */
551
int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
552
0
{
553
0
    return X509_PURPOSE_set(&param->purpose, purpose);
554
0
}
555
556
int X509_VERIFY_PARAM_get_purpose(const X509_VERIFY_PARAM *param)
557
0
{
558
0
    return param->purpose;
559
0
}
560
561
int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
562
0
{
563
0
    return X509_TRUST_set(&param->trust, trust);
564
0
}
565
566
void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
567
0
{
568
0
    param->depth = depth;
569
0
}
570
571
void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
572
0
{
573
0
    param->auth_level = auth_level;
574
0
}
575
576
time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param)
577
0
{
578
    /* This will be in the time_t range, because the only setter uses time_t */
579
0
    return (time_t)param->check_time;
580
0
}
581
582
void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
583
0
{
584
0
    param->check_time = (int64_t)t;
585
0
    param->flags |= X509_V_FLAG_USE_CHECK_TIME;
586
0
}
587
588
void ossl_x509_verify_param_set_time_posix(X509_VERIFY_PARAM *param, int64_t t)
589
0
{
590
0
    param->check_time = t;
591
0
    param->flags |= X509_V_FLAG_USE_CHECK_TIME;
592
0
}
593
594
int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
595
    ASN1_OBJECT *policy)
596
0
{
597
0
    if (param->policies == NULL) {
598
0
        param->policies = sk_ASN1_OBJECT_new_null();
599
0
        if (param->policies == NULL)
600
0
            return 0;
601
0
    }
602
603
0
    if (sk_ASN1_OBJECT_push(param->policies, policy) <= 0)
604
0
        return 0;
605
0
    return 1;
606
0
}
607
608
int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
609
    STACK_OF(ASN1_OBJECT) *policies)
610
0
{
611
0
    int i;
612
0
    ASN1_OBJECT *oid, *doid;
613
614
0
    if (param == NULL) {
615
0
        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
616
0
        return 0;
617
0
    }
618
0
    sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
619
620
0
    if (policies == NULL) {
621
0
        param->policies = NULL;
622
0
        return 1;
623
0
    }
624
625
0
    param->policies = sk_ASN1_OBJECT_new_null();
626
0
    if (param->policies == NULL)
627
0
        return 0;
628
629
0
    for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
630
0
        oid = sk_ASN1_OBJECT_value(policies, i);
631
0
        doid = OBJ_dup(oid);
632
0
        if (doid == NULL)
633
0
            return 0;
634
0
        if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
635
0
            ASN1_OBJECT_free(doid);
636
0
            return 0;
637
0
        }
638
0
    }
639
0
    param->flags |= X509_V_FLAG_POLICY_CHECK;
640
0
    return 1;
641
0
}
642
643
char *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int idx)
644
0
{
645
0
    X509_BUFFER *buf = sk_X509_BUFFER_value(param->hosts, idx);
646
647
0
    return (buf != NULL) ? (char *)buf->data : NULL;
648
0
}
649
650
int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
651
    const char *dnsname, size_t len)
652
0
{
653
0
    clear_buffer_stack(&param->hosts);
654
0
    if (dnsname == NULL)
655
0
        return 1;
656
0
    if (len == 0)
657
0
        len = strlen(dnsname);
658
0
    if (len == 0)
659
0
        return 1;
660
0
    return X509_VERIFY_PARAM_add1_host(param, dnsname, len);
661
0
}
662
663
int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
664
    const char *dnsname, size_t len)
665
0
{
666
0
    if (dnsname == NULL)
667
0
        return 1;
668
0
    if (len == 0)
669
0
        len = strlen(dnsname);
670
0
    if (len == 0)
671
0
        return 1;
672
0
    if (!validate_string_name(dnsname, &len))
673
0
        return 0;
674
0
    if (param->validate_host != NULL) {
675
0
        if (!param->validate_host(dnsname, len))
676
0
            return 0;
677
0
    } else {
678
0
        if (!validate_hostname_part(dnsname, len, OSSL_CHARSET_ASCII_ALNUM))
679
0
            return 0;
680
0
    }
681
0
    return add_string_to_buffer_stack(&param->hosts, (const uint8_t *)dnsname, len);
682
0
}
683
684
void X509_VERIFY_PARAM_set1_host_input_validation(X509_VERIFY_PARAM *param,
685
    int (*validate_host)(const char *name, size_t len))
686
0
{
687
0
    param->validate_host = validate_host;
688
0
}
689
690
int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
691
    const uint8_t *ip, size_t len)
692
0
{
693
0
    clear_buffer_stack(&param->ips);
694
0
    if (ip == NULL)
695
0
        return 1;
696
0
    return X509_VERIFY_PARAM_add1_ip(param, ip, len);
697
0
}
698
699
int X509_VERIFY_PARAM_add1_ip(X509_VERIFY_PARAM *param,
700
    const uint8_t *ip, size_t len)
701
0
{
702
0
    if (param->validate_ip != NULL) {
703
0
        if (!param->validate_ip(ip, len))
704
0
            return 0;
705
0
    } else {
706
0
        if (!validate_ip_name(ip, len))
707
0
            return 0;
708
0
    }
709
0
    return add_bytes_to_buffer_stack(&param->ips, ip, len);
710
0
}
711
712
void X509_VERIFY_PARAM_set1_ip_input_validation(X509_VERIFY_PARAM *param,
713
    int (*validate_ip)(const uint8_t *name, size_t len))
714
0
{
715
0
    param->validate_ip = validate_ip;
716
0
}
717
718
char *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param)
719
0
{
720
0
    X509_BUFFER *buf = sk_X509_BUFFER_value(param->rfc822s, 0);
721
722
0
    if ((buf = sk_X509_BUFFER_value(param->rfc822s, 0)) != NULL
723
0
        || (buf = sk_X509_BUFFER_value(param->smtputf8s, 0)) != NULL)
724
0
        return (char *)buf->data;
725
726
0
    return NULL;
727
0
}
728
729
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
730
    const char *email, size_t len)
731
0
{
732
0
    int ret = 0;
733
734
0
    if (X509_VERIFY_PARAM_set1_smtputf8(param, email, len))
735
0
        ret = 1;
736
0
    if (X509_VERIFY_PARAM_set1_rfc822(param, email, len))
737
0
        ret = 1;
738
739
0
    return ret;
740
0
}
741
742
int X509_VERIFY_PARAM_set1_smtputf8(X509_VERIFY_PARAM *param,
743
    const char *email, size_t len)
744
0
{
745
0
    clear_buffer_stack(&param->smtputf8s);
746
0
    if (email == NULL)
747
0
        return 1;
748
0
    return X509_VERIFY_PARAM_add1_smtputf8(param, email, len);
749
0
}
750
751
int X509_VERIFY_PARAM_add1_smtputf8(X509_VERIFY_PARAM *param,
752
    const char *email, size_t len)
753
0
{
754
0
    if (len == 0)
755
0
        len = strlen(email);
756
0
    if (!validate_string_name(email, &len))
757
0
        return 0;
758
0
    if (param->validate_smtputf8 != NULL) {
759
0
        if (!param->validate_smtputf8(email, len))
760
0
            return 0;
761
0
    } else {
762
0
        if (!validate_email_name(email, len, /*rfc822 =*/0))
763
0
            return 0;
764
0
    }
765
766
0
    return add_string_to_buffer_stack(&param->smtputf8s,
767
0
        (const uint8_t *)email, len);
768
0
}
769
770
void X509_VERIFY_PARAM_set1_smtputf8_input_validation(X509_VERIFY_PARAM *param,
771
    int (*validate_smtputf8)(const char *name, size_t len))
772
0
{
773
0
    param->validate_smtputf8 = validate_smtputf8;
774
0
}
775
776
int X509_VERIFY_PARAM_set1_rfc822(X509_VERIFY_PARAM *param,
777
    const char *email, size_t len)
778
0
{
779
0
    clear_buffer_stack(&param->rfc822s);
780
0
    if (email == NULL)
781
0
        return 1;
782
0
    return X509_VERIFY_PARAM_add1_rfc822(param, email, len);
783
0
}
784
785
int X509_VERIFY_PARAM_add1_rfc822(X509_VERIFY_PARAM *param,
786
    const char *email, size_t len)
787
0
{
788
0
    if (len == 0)
789
0
        len = strlen(email);
790
0
    if (!validate_string_name(email, &len))
791
0
        return 0;
792
0
    if (param->validate_rfc822 != NULL) {
793
0
        if (!param->validate_rfc822(email, len))
794
0
            return 0;
795
0
    } else {
796
0
        if (!validate_email_name(email, len, /*rfc822 =*/1))
797
0
            return 0;
798
0
    }
799
800
0
    return add_string_to_buffer_stack(&param->rfc822s,
801
0
        (const uint8_t *)email, len);
802
0
}
803
804
void X509_VERIFY_PARAM_set1_rfc822_input_validation(X509_VERIFY_PARAM *param,
805
    int (*validate_rfc822)(const char *name, size_t len))
806
0
{
807
0
    param->validate_rfc822 = validate_rfc822;
808
0
}
809
810
void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
811
    unsigned int flags)
812
0
{
813
0
    param->hostflags = flags;
814
0
}
815
816
unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param)
817
0
{
818
0
    return param->hostflags;
819
0
}
820
821
char *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param)
822
0
{
823
0
    return param->peername;
824
0
}
825
826
/*
827
 * Move peername from one param structure to another, freeing any name present
828
 * at the target.  If the source is a NULL parameter structure, free and zero
829
 * the target peername.
830
 */
831
void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to,
832
    X509_VERIFY_PARAM *from)
833
0
{
834
0
    char *peername = (from != NULL) ? from->peername : NULL;
835
836
0
    if (to->peername != peername) {
837
0
        OPENSSL_free(to->peername);
838
0
        to->peername = peername;
839
0
    }
840
0
    if (from != NULL)
841
0
        from->peername = NULL;
842
0
}
843
844
static const unsigned char *int_X509_VERIFY_PARAM_get0_ip(X509_VERIFY_PARAM *param, size_t *plen, size_t idx)
845
0
{
846
0
    X509_BUFFER *buf;
847
848
0
    if (idx > INT_MAX)
849
0
        return NULL;
850
851
0
    if (param == NULL || param->ips == NULL) {
852
0
        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER);
853
0
        return NULL;
854
0
    }
855
856
0
    buf = sk_X509_BUFFER_value(param->ips, (int)idx);
857
858
0
    if (buf != NULL) {
859
0
        if (plen != NULL)
860
0
            *plen = buf->len;
861
0
        return (unsigned char *)buf->data;
862
0
    }
863
0
    return NULL;
864
0
}
865
866
char *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param)
867
0
{
868
0
    size_t iplen;
869
0
    const unsigned char *ip = int_X509_VERIFY_PARAM_get0_ip(param, &iplen, 0);
870
871
0
    return ip == NULL ? NULL : ossl_ipaddr_to_asc(ip, (int)iplen);
872
0
}
873
874
int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
875
0
{
876
0
    unsigned char ipout[16];
877
0
    size_t iplen;
878
879
0
    if (ipasc == NULL)
880
0
        return X509_VERIFY_PARAM_set1_ip(param, NULL, 0);
881
0
    if ((iplen = (size_t)ossl_a2i_ipadd(ipout, ipasc)) == 0)
882
0
        return 0;
883
0
    return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
884
0
}
885
886
int X509_VERIFY_PARAM_add1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
887
0
{
888
0
    unsigned char ipout[16];
889
0
    size_t iplen;
890
891
0
    if ((iplen = (size_t)ossl_a2i_ipadd(ipout, ipasc)) == 0)
892
0
        return 0;
893
0
    return X509_VERIFY_PARAM_add1_ip(param, ipout, iplen);
894
0
}
895
896
int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
897
0
{
898
0
    return param->depth;
899
0
}
900
901
int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param)
902
0
{
903
0
    return param->auth_level;
904
0
}
905
906
const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
907
0
{
908
0
    return param->name;
909
0
}
910
911
/*
912
 * Default verify parameters: these are used for various applications and can
913
 * be overridden by the user specified table. NB: the 'name' field *must* be
914
 * in alphabetical order because it will be searched using OBJ_search.
915
 */
916
917
static const X509_VERIFY_PARAM default_table[] = {
918
    {
919
        .name = "code_sign", /* Code sign parameters */
920
        .purpose = X509_PURPOSE_CODE_SIGN,
921
        .trust = X509_TRUST_OBJECT_SIGN,
922
        .depth = -1,
923
        .auth_level = -1,
924
    },
925
    {
926
        .name = "default", /* X509 default parameters */
927
        .flags = X509_V_FLAG_TRUSTED_FIRST,
928
        .depth = 100,
929
        .auth_level = -1,
930
    },
931
    {
932
        .name = "pkcs7", /* S/MIME sign parameters */
933
        .purpose = X509_PURPOSE_SMIME_SIGN,
934
        .trust = X509_TRUST_EMAIL,
935
        .depth = -1,
936
        .auth_level = -1,
937
    },
938
    {
939
        .name = "smime_encrypt", /* S/MIME encryption parameters */
940
        .purpose = X509_PURPOSE_SMIME_ENCRYPT,
941
        .trust = X509_TRUST_EMAIL,
942
        .depth = -1,
943
        .auth_level = -1,
944
    },
945
    {
946
        .name = "smime_sign", /* S/MIME signature parameters */
947
        .purpose = X509_PURPOSE_SMIME_SIGN,
948
        .trust = X509_TRUST_EMAIL,
949
        .depth = -1,
950
        .auth_level = -1,
951
    },
952
    {
953
        .name = "ssl_client", /* SSL/TLS client parameters */
954
        .purpose = X509_PURPOSE_SSL_CLIENT,
955
        .trust = X509_TRUST_SSL_CLIENT,
956
        .depth = -1,
957
        .auth_level = -1,
958
    },
959
    {
960
        .name = "ssl_server", /* SSL/TLS server parameters */
961
        .purpose = X509_PURPOSE_SSL_SERVER,
962
        .trust = X509_TRUST_SSL_SERVER,
963
        .depth = -1,
964
        .auth_level = -1,
965
    }
966
};
967
968
static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
969
970
static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
971
0
{
972
0
    return strcmp(a->name, b->name);
973
0
}
974
975
DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table);
976
IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table);
977
978
static int param_cmp(const X509_VERIFY_PARAM *const *a,
979
    const X509_VERIFY_PARAM *const *b)
980
0
{
981
0
    return strcmp((*a)->name, (*b)->name);
982
0
}
983
984
int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
985
0
{
986
0
    int idx;
987
0
    X509_VERIFY_PARAM *ptmp;
988
989
0
    if (param_table == NULL) {
990
0
        param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
991
0
        if (param_table == NULL)
992
0
            return 0;
993
0
    } else {
994
0
        idx = sk_X509_VERIFY_PARAM_find(param_table, param);
995
0
        if (idx >= 0) {
996
0
            ptmp = sk_X509_VERIFY_PARAM_delete(param_table, idx);
997
0
            X509_VERIFY_PARAM_free(ptmp);
998
0
        }
999
0
    }
1000
1001
0
    if (sk_X509_VERIFY_PARAM_push(param_table, param) <= 0)
1002
0
        return 0;
1003
0
    return 1;
1004
0
}
1005
1006
int X509_VERIFY_PARAM_get_count(void)
1007
0
{
1008
0
    int num = OSSL_NELEM(default_table);
1009
1010
0
    if (param_table != NULL)
1011
0
        num += sk_X509_VERIFY_PARAM_num(param_table);
1012
0
    return num;
1013
0
}
1014
1015
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
1016
0
{
1017
0
    int num = OSSL_NELEM(default_table);
1018
1019
0
    if (id < 0) {
1020
0
        ERR_raise(ERR_LIB_X509, ERR_R_PASSED_INVALID_ARGUMENT);
1021
0
        return NULL;
1022
0
    }
1023
1024
0
    if (id < num)
1025
0
        return default_table + id;
1026
0
    return sk_X509_VERIFY_PARAM_value(param_table, id - num);
1027
0
}
1028
1029
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
1030
0
{
1031
0
    int idx;
1032
0
    X509_VERIFY_PARAM pm;
1033
1034
0
    pm.name = (char *)name;
1035
0
    if (param_table != NULL) {
1036
        /* Ideally, this would be done under a lock */
1037
0
        sk_X509_VERIFY_PARAM_sort(param_table);
1038
0
        idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
1039
0
        if (idx >= 0)
1040
0
            return sk_X509_VERIFY_PARAM_value(param_table, idx);
1041
0
    }
1042
0
    return OBJ_bsearch_table(&pm, default_table, OSSL_NELEM(default_table));
1043
0
}
1044
1045
void X509_VERIFY_PARAM_table_cleanup(void)
1046
0
{
1047
0
    sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
1048
    param_table = NULL;
1049
0
}