Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/x509v3/v3_utl.c
Line
Count
Source (jump to first uncovered line)
1
/* v3_utl.c */
2
/*
3
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4
 * project.
5
 */
6
/* ====================================================================
7
 * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 *
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 *
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in
18
 *    the documentation and/or other materials provided with the
19
 *    distribution.
20
 *
21
 * 3. All advertising materials mentioning features or use of this
22
 *    software must display the following acknowledgment:
23
 *    "This product includes software developed by the OpenSSL Project
24
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25
 *
26
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27
 *    endorse or promote products derived from this software without
28
 *    prior written permission. For written permission, please contact
29
 *    licensing@OpenSSL.org.
30
 *
31
 * 5. Products derived from this software may not be called "OpenSSL"
32
 *    nor may "OpenSSL" appear in their names without prior written
33
 *    permission of the OpenSSL Project.
34
 *
35
 * 6. Redistributions of any form whatsoever must retain the following
36
 *    acknowledgment:
37
 *    "This product includes software developed by the OpenSSL Project
38
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51
 * OF THE POSSIBILITY OF SUCH DAMAGE.
52
 * ====================================================================
53
 *
54
 * This product includes cryptographic software written by Eric Young
55
 * (eay@cryptsoft.com).  This product includes software written by Tim
56
 * Hudson (tjh@cryptsoft.com).
57
 *
58
 */
59
/* X509 v3 extension utilities */
60
61
#include <stdio.h>
62
#include <ctype.h>
63
#include "cryptlib.h"
64
#include <openssl/conf.h>
65
#include <openssl/x509v3.h>
66
#include <openssl/bn.h>
67
68
static char *strip_spaces(char *name);
69
static int sk_strcmp(const char *const *a, const char *const *b);
70
static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
71
                                           GENERAL_NAMES *gens);
72
static void str_free(OPENSSL_STRING str);
73
static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email);
74
75
static int ipv4_from_asc(unsigned char *v4, const char *in);
76
static int ipv6_from_asc(unsigned char *v6, const char *in);
77
static int ipv6_cb(const char *elem, int len, void *usr);
78
static int ipv6_hex(unsigned char *out, const char *in, int inlen);
79
80
/* Add a CONF_VALUE name value pair to stack */
81
82
int X509V3_add_value(const char *name, const char *value,
83
                     STACK_OF(CONF_VALUE) **extlist)
84
0
{
85
0
    CONF_VALUE *vtmp = NULL;
86
0
    char *tname = NULL, *tvalue = NULL;
87
0
    if (name && !(tname = BUF_strdup(name)))
88
0
        goto err;
89
0
    if (value && !(tvalue = BUF_strdup(value)))
90
0
        goto err;
91
0
    if (!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))))
92
0
        goto err;
93
0
    if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null()))
94
0
        goto err;
95
0
    vtmp->section = NULL;
96
0
    vtmp->name = tname;
97
0
    vtmp->value = tvalue;
98
0
    if (!sk_CONF_VALUE_push(*extlist, vtmp))
99
0
        goto err;
100
0
    return 1;
101
0
 err:
102
0
    X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE);
103
0
    if (vtmp)
104
0
        OPENSSL_free(vtmp);
105
0
    if (tname)
106
0
        OPENSSL_free(tname);
107
0
    if (tvalue)
108
0
        OPENSSL_free(tvalue);
109
0
    return 0;
110
0
}
111
112
int X509V3_add_value_uchar(const char *name, const unsigned char *value,
113
                           STACK_OF(CONF_VALUE) **extlist)
114
0
{
115
0
    return X509V3_add_value(name, (const char *)value, extlist);
116
0
}
117
118
/* Free function for STACK_OF(CONF_VALUE) */
119
120
void X509V3_conf_free(CONF_VALUE *conf)
121
0
{
122
0
    if (!conf)
123
0
        return;
124
0
    if (conf->name)
125
0
        OPENSSL_free(conf->name);
126
0
    if (conf->value)
127
0
        OPENSSL_free(conf->value);
128
0
    if (conf->section)
129
0
        OPENSSL_free(conf->section);
130
0
    OPENSSL_free(conf);
131
0
}
132
133
int X509V3_add_value_bool(const char *name, int asn1_bool,
134
                          STACK_OF(CONF_VALUE) **extlist)
135
0
{
136
0
    if (asn1_bool)
137
0
        return X509V3_add_value(name, "TRUE", extlist);
138
0
    return X509V3_add_value(name, "FALSE", extlist);
139
0
}
140
141
int X509V3_add_value_bool_nf(char *name, int asn1_bool,
142
                             STACK_OF(CONF_VALUE) **extlist)
143
0
{
144
0
    if (asn1_bool)
145
0
        return X509V3_add_value(name, "TRUE", extlist);
146
0
    return 1;
147
0
}
148
149
char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
150
0
{
151
0
    BIGNUM *bntmp = NULL;
152
0
    char *strtmp = NULL;
153
0
    if (!a)
154
0
        return NULL;
155
0
    if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
156
0
        !(strtmp = BN_bn2dec(bntmp)))
157
0
        X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
158
0
    BN_free(bntmp);
159
0
    return strtmp;
160
0
}
161
162
char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
163
0
{
164
0
    BIGNUM *bntmp = NULL;
165
0
    char *strtmp = NULL;
166
0
    if (!a)
167
0
        return NULL;
168
0
    if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
169
0
        !(strtmp = BN_bn2dec(bntmp)))
170
0
        X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
171
0
    BN_free(bntmp);
172
0
    return strtmp;
173
0
}
174
175
ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
176
0
{
177
0
    BIGNUM *bn = NULL;
178
0
    ASN1_INTEGER *aint;
179
0
    int isneg, ishex;
180
0
    int ret;
181
0
    if (!value) {
182
0
        X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
183
0
        return 0;
184
0
    }
185
0
    bn = BN_new();
186
0
    if (value[0] == '-') {
187
0
        value++;
188
0
        isneg = 1;
189
0
    } else
190
0
        isneg = 0;
191
192
0
    if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
193
0
        value += 2;
194
0
        ishex = 1;
195
0
    } else
196
0
        ishex = 0;
197
198
0
    if (ishex)
199
0
        ret = BN_hex2bn(&bn, value);
200
0
    else
201
0
        ret = BN_dec2bn(&bn, value);
202
203
0
    if (!ret || value[ret]) {
204
0
        BN_free(bn);
205
0
        X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
206
0
        return 0;
207
0
    }
208
209
0
    if (isneg && BN_is_zero(bn))
210
0
        isneg = 0;
211
212
0
    aint = BN_to_ASN1_INTEGER(bn, NULL);
213
0
    BN_free(bn);
214
0
    if (!aint) {
215
0
        X509V3err(X509V3_F_S2I_ASN1_INTEGER,
216
0
                  X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
217
0
        return 0;
218
0
    }
219
0
    if (isneg)
220
0
        aint->type |= V_ASN1_NEG;
221
0
    return aint;
222
0
}
223
224
int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
225
                         STACK_OF(CONF_VALUE) **extlist)
226
0
{
227
0
    char *strtmp;
228
0
    int ret;
229
0
    if (!aint)
230
0
        return 1;
231
0
    if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint)))
232
0
        return 0;
233
0
    ret = X509V3_add_value(name, strtmp, extlist);
234
0
    OPENSSL_free(strtmp);
235
0
    return ret;
236
0
}
237
238
int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
239
0
{
240
0
    char *btmp;
241
0
    if (!(btmp = value->value))
242
0
        goto err;
243
0
    if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true")
244
0
        || !strcmp(btmp, "Y") || !strcmp(btmp, "y")
245
0
        || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) {
246
0
        *asn1_bool = 0xff;
247
0
        return 1;
248
0
    } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false")
249
0
               || !strcmp(btmp, "N") || !strcmp(btmp, "n")
250
0
               || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) {
251
0
        *asn1_bool = 0;
252
0
        return 1;
253
0
    }
254
0
 err:
255
0
    X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,
256
0
              X509V3_R_INVALID_BOOLEAN_STRING);
257
0
    X509V3_conf_err(value);
258
0
    return 0;
259
0
}
260
261
int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint)
262
0
{
263
0
    ASN1_INTEGER *itmp;
264
0
    if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) {
265
0
        X509V3_conf_err(value);
266
0
        return 0;
267
0
    }
268
0
    *aint = itmp;
269
0
    return 1;
270
0
}
271
272
0
#define HDR_NAME        1
273
0
#define HDR_VALUE       2
274
275
/*
276
 * #define DEBUG
277
 */
278
279
STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
280
0
{
281
0
    char *p, *q, c;
282
0
    char *ntmp, *vtmp;
283
0
    STACK_OF(CONF_VALUE) *values = NULL;
284
0
    char *linebuf;
285
0
    int state;
286
    /* We are going to modify the line so copy it first */
287
0
    linebuf = BUF_strdup(line);
288
0
    if (linebuf == NULL) {
289
0
        X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE);
290
0
        goto err;
291
0
    }
292
0
    state = HDR_NAME;
293
0
    ntmp = NULL;
294
    /* Go through all characters */
295
0
    for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
296
0
         p++) {
297
298
0
        switch (state) {
299
0
        case HDR_NAME:
300
0
            if (c == ':') {
301
0
                state = HDR_VALUE;
302
0
                *p = 0;
303
0
                ntmp = strip_spaces(q);
304
0
                if (!ntmp) {
305
0
                    X509V3err(X509V3_F_X509V3_PARSE_LIST,
306
0
                              X509V3_R_INVALID_NULL_NAME);
307
0
                    goto err;
308
0
                }
309
0
                q = p + 1;
310
0
            } else if (c == ',') {
311
0
                *p = 0;
312
0
                ntmp = strip_spaces(q);
313
0
                q = p + 1;
314
#if 0
315
                printf("%s\n", ntmp);
316
#endif
317
0
                if (!ntmp) {
318
0
                    X509V3err(X509V3_F_X509V3_PARSE_LIST,
319
0
                              X509V3_R_INVALID_NULL_NAME);
320
0
                    goto err;
321
0
                }
322
0
                X509V3_add_value(ntmp, NULL, &values);
323
0
            }
324
0
            break;
325
326
0
        case HDR_VALUE:
327
0
            if (c == ',') {
328
0
                state = HDR_NAME;
329
0
                *p = 0;
330
0
                vtmp = strip_spaces(q);
331
#if 0
332
                printf("%s\n", ntmp);
333
#endif
334
0
                if (!vtmp) {
335
0
                    X509V3err(X509V3_F_X509V3_PARSE_LIST,
336
0
                              X509V3_R_INVALID_NULL_VALUE);
337
0
                    goto err;
338
0
                }
339
0
                X509V3_add_value(ntmp, vtmp, &values);
340
0
                ntmp = NULL;
341
0
                q = p + 1;
342
0
            }
343
344
0
        }
345
0
    }
346
347
0
    if (state == HDR_VALUE) {
348
0
        vtmp = strip_spaces(q);
349
#if 0
350
        printf("%s=%s\n", ntmp, vtmp);
351
#endif
352
0
        if (!vtmp) {
353
0
            X509V3err(X509V3_F_X509V3_PARSE_LIST,
354
0
                      X509V3_R_INVALID_NULL_VALUE);
355
0
            goto err;
356
0
        }
357
0
        X509V3_add_value(ntmp, vtmp, &values);
358
0
    } else {
359
0
        ntmp = strip_spaces(q);
360
#if 0
361
        printf("%s\n", ntmp);
362
#endif
363
0
        if (!ntmp) {
364
0
            X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
365
0
            goto err;
366
0
        }
367
0
        X509V3_add_value(ntmp, NULL, &values);
368
0
    }
369
0
    OPENSSL_free(linebuf);
370
0
    return values;
371
372
0
 err:
373
0
    OPENSSL_free(linebuf);
374
0
    sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
375
0
    return NULL;
376
377
0
}
378
379
/* Delete leading and trailing spaces from a string */
380
static char *strip_spaces(char *name)
381
0
{
382
0
    char *p, *q;
383
    /* Skip over leading spaces */
384
0
    p = name;
385
0
    while (*p && isspace((unsigned char)*p))
386
0
        p++;
387
0
    if (!*p)
388
0
        return NULL;
389
0
    q = p + strlen(p) - 1;
390
0
    while ((q != p) && isspace((unsigned char)*q))
391
0
        q--;
392
0
    if (p != q)
393
0
        q[1] = 0;
394
0
    if (!*p)
395
0
        return NULL;
396
0
    return p;
397
0
}
398
399
/* hex string utilities */
400
401
/*
402
 * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
403
 * hex representation @@@ (Contents of buffer are always kept in ASCII, also
404
 * on EBCDIC machines)
405
 */
406
407
char *hex_to_string(const unsigned char *buffer, long len)
408
0
{
409
0
    char *tmp, *q;
410
0
    const unsigned char *p;
411
0
    int i;
412
0
    const static char hexdig[] = "0123456789ABCDEF";
413
0
    if (!buffer || !len)
414
0
        return NULL;
415
0
    if (!(tmp = OPENSSL_malloc(len * 3 + 1))) {
416
0
        X509V3err(X509V3_F_HEX_TO_STRING, ERR_R_MALLOC_FAILURE);
417
0
        return NULL;
418
0
    }
419
0
    q = tmp;
420
0
    for (i = 0, p = buffer; i < len; i++, p++) {
421
0
        *q++ = hexdig[(*p >> 4) & 0xf];
422
0
        *q++ = hexdig[*p & 0xf];
423
0
        *q++ = ':';
424
0
    }
425
0
    q[-1] = 0;
426
#ifdef CHARSET_EBCDIC
427
    ebcdic2ascii(tmp, tmp, q - tmp - 1);
428
#endif
429
430
0
    return tmp;
431
0
}
432
433
/*
434
 * Give a string of hex digits convert to a buffer
435
 */
436
437
unsigned char *string_to_hex(const char *str, long *len)
438
0
{
439
0
    unsigned char *hexbuf, *q;
440
0
    unsigned char ch, cl, *p;
441
0
    if (!str) {
442
0
        X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_INVALID_NULL_ARGUMENT);
443
0
        return NULL;
444
0
    }
445
0
    if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1)))
446
0
        goto err;
447
0
    for (p = (unsigned char *)str, q = hexbuf; *p;) {
448
0
        ch = *p++;
449
#ifdef CHARSET_EBCDIC
450
        ch = os_toebcdic[ch];
451
#endif
452
0
        if (ch == ':')
453
0
            continue;
454
0
        cl = *p++;
455
#ifdef CHARSET_EBCDIC
456
        cl = os_toebcdic[cl];
457
#endif
458
0
        if (!cl) {
459
0
            X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ODD_NUMBER_OF_DIGITS);
460
0
            OPENSSL_free(hexbuf);
461
0
            return NULL;
462
0
        }
463
0
        if (isupper(ch))
464
0
            ch = tolower(ch);
465
0
        if (isupper(cl))
466
0
            cl = tolower(cl);
467
468
0
        if ((ch >= '0') && (ch <= '9'))
469
0
            ch -= '0';
470
0
        else if ((ch >= 'a') && (ch <= 'f'))
471
0
            ch -= 'a' - 10;
472
0
        else
473
0
            goto badhex;
474
475
0
        if ((cl >= '0') && (cl <= '9'))
476
0
            cl -= '0';
477
0
        else if ((cl >= 'a') && (cl <= 'f'))
478
0
            cl -= 'a' - 10;
479
0
        else
480
0
            goto badhex;
481
482
0
        *q++ = (ch << 4) | cl;
483
0
    }
484
485
0
    if (len)
486
0
        *len = q - hexbuf;
487
488
0
    return hexbuf;
489
490
0
 err:
491
0
    if (hexbuf)
492
0
        OPENSSL_free(hexbuf);
493
0
    X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE);
494
0
    return NULL;
495
496
0
 badhex:
497
0
    OPENSSL_free(hexbuf);
498
0
    X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT);
499
0
    return NULL;
500
501
0
}
502
503
/*
504
 * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
505
 */
506
507
int name_cmp(const char *name, const char *cmp)
508
0
{
509
0
    int len, ret;
510
0
    char c;
511
0
    len = strlen(cmp);
512
0
    if ((ret = strncmp(name, cmp, len)))
513
0
        return ret;
514
0
    c = name[len];
515
0
    if (!c || (c == '.'))
516
0
        return 0;
517
0
    return 1;
518
0
}
519
520
static int sk_strcmp(const char *const *a, const char *const *b)
521
0
{
522
0
    return strcmp(*a, *b);
523
0
}
524
525
STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
526
0
{
527
0
    GENERAL_NAMES *gens;
528
0
    STACK_OF(OPENSSL_STRING) *ret;
529
530
0
    gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
531
0
    ret = get_email(X509_get_subject_name(x), gens);
532
0
    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
533
0
    return ret;
534
0
}
535
536
STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
537
0
{
538
0
    AUTHORITY_INFO_ACCESS *info;
539
0
    STACK_OF(OPENSSL_STRING) *ret = NULL;
540
0
    int i;
541
542
0
    info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
543
0
    if (!info)
544
0
        return NULL;
545
0
    for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
546
0
        ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
547
0
        if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
548
0
            if (ad->location->type == GEN_URI) {
549
0
                if (!append_ia5
550
0
                    (&ret, ad->location->d.uniformResourceIdentifier))
551
0
                    break;
552
0
            }
553
0
        }
554
0
    }
555
0
    AUTHORITY_INFO_ACCESS_free(info);
556
0
    return ret;
557
0
}
558
559
STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
560
0
{
561
0
    GENERAL_NAMES *gens;
562
0
    STACK_OF(X509_EXTENSION) *exts;
563
0
    STACK_OF(OPENSSL_STRING) *ret;
564
565
0
    exts = X509_REQ_get_extensions(x);
566
0
    gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
567
0
    ret = get_email(X509_REQ_get_subject_name(x), gens);
568
0
    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
569
0
    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
570
0
    return ret;
571
0
}
572
573
static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
574
                                           GENERAL_NAMES *gens)
575
0
{
576
0
    STACK_OF(OPENSSL_STRING) *ret = NULL;
577
0
    X509_NAME_ENTRY *ne;
578
0
    ASN1_IA5STRING *email;
579
0
    GENERAL_NAME *gen;
580
0
    int i;
581
    /* Now add any email address(es) to STACK */
582
0
    i = -1;
583
    /* First supplied X509_NAME */
584
0
    while ((i = X509_NAME_get_index_by_NID(name,
585
0
                                           NID_pkcs9_emailAddress, i)) >= 0) {
586
0
        ne = X509_NAME_get_entry(name, i);
587
0
        email = X509_NAME_ENTRY_get_data(ne);
588
0
        if (!append_ia5(&ret, email))
589
0
            return NULL;
590
0
    }
591
0
    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
592
0
        gen = sk_GENERAL_NAME_value(gens, i);
593
0
        if (gen->type != GEN_EMAIL)
594
0
            continue;
595
0
        if (!append_ia5(&ret, gen->d.ia5))
596
0
            return NULL;
597
0
    }
598
0
    return ret;
599
0
}
600
601
static void str_free(OPENSSL_STRING str)
602
0
{
603
0
    OPENSSL_free(str);
604
0
}
605
606
static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email)
607
0
{
608
0
    char *emtmp;
609
    /* First some sanity checks */
610
0
    if (email->type != V_ASN1_IA5STRING)
611
0
        return 1;
612
0
    if (!email->data || !email->length)
613
0
        return 1;
614
0
    if (!*sk)
615
0
        *sk = sk_OPENSSL_STRING_new(sk_strcmp);
616
0
    if (!*sk)
617
0
        return 0;
618
    /* Don't add duplicates */
619
0
    if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1)
620
0
        return 1;
621
0
    emtmp = BUF_strdup((char *)email->data);
622
0
    if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
623
0
        X509_email_free(*sk);
624
0
        *sk = NULL;
625
0
        return 0;
626
0
    }
627
0
    return 1;
628
0
}
629
630
void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
631
0
{
632
0
    sk_OPENSSL_STRING_pop_free(sk, str_free);
633
0
}
634
635
typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
636
                         const unsigned char *subject, size_t subject_len,
637
                         unsigned int flags);
638
639
/* Skip pattern prefix to match "wildcard" subject */
640
static void skip_prefix(const unsigned char **p, size_t *plen,
641
                        const unsigned char *subject, size_t subject_len,
642
                        unsigned int flags)
643
0
{
644
0
    const unsigned char *pattern = *p;
645
0
    size_t pattern_len = *plen;
646
647
    /*
648
     * If subject starts with a leading '.' followed by more octets, and
649
     * pattern is longer, compare just an equal-length suffix with the
650
     * full subject (starting at the '.'), provided the prefix contains
651
     * no NULs.
652
     */
653
0
    if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
654
0
        return;
655
656
0
    while (pattern_len > subject_len && *pattern) {
657
0
        if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
658
0
            *pattern == '.')
659
0
            break;
660
0
        ++pattern;
661
0
        --pattern_len;
662
0
    }
663
664
    /* Skip if entire prefix acceptable */
665
0
    if (pattern_len == subject_len) {
666
0
        *p = pattern;
667
0
        *plen = pattern_len;
668
0
    }
669
0
}
670
671
/* Compare while ASCII ignoring case. */
672
static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
673
                        const unsigned char *subject, size_t subject_len,
674
                        unsigned int flags)
675
0
{
676
0
    skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
677
0
    if (pattern_len != subject_len)
678
0
        return 0;
679
0
    while (pattern_len) {
680
0
        unsigned char l = *pattern;
681
0
        unsigned char r = *subject;
682
        /* The pattern must not contain NUL characters. */
683
0
        if (l == 0)
684
0
            return 0;
685
0
        if (l != r) {
686
0
            if ('A' <= l && l <= 'Z')
687
0
                l = (l - 'A') + 'a';
688
0
            if ('A' <= r && r <= 'Z')
689
0
                r = (r - 'A') + 'a';
690
0
            if (l != r)
691
0
                return 0;
692
0
        }
693
0
        ++pattern;
694
0
        ++subject;
695
0
        --pattern_len;
696
0
    }
697
0
    return 1;
698
0
}
699
700
/* Compare using memcmp. */
701
static int equal_case(const unsigned char *pattern, size_t pattern_len,
702
                      const unsigned char *subject, size_t subject_len,
703
                      unsigned int flags)
704
0
{
705
0
    skip_prefix(&pattern, &pattern_len, subject, subject_len, flags);
706
0
    if (pattern_len != subject_len)
707
0
        return 0;
708
0
    return !memcmp(pattern, subject, pattern_len);
709
0
}
710
711
/*
712
 * RFC 5280, section 7.5, requires that only the domain is compared in a
713
 * case-insensitive manner.
714
 */
715
static int equal_email(const unsigned char *a, size_t a_len,
716
                       const unsigned char *b, size_t b_len,
717
                       unsigned int unused_flags)
718
0
{
719
0
    size_t i = a_len;
720
0
    if (a_len != b_len)
721
0
        return 0;
722
    /*
723
     * We search backwards for the '@' character, so that we do not have to
724
     * deal with quoted local-parts.  The domain part is compared in a
725
     * case-insensitive manner.
726
     */
727
0
    while (i > 0) {
728
0
        --i;
729
0
        if (a[i] == '@' || b[i] == '@') {
730
0
            if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0))
731
0
                return 0;
732
0
            break;
733
0
        }
734
0
    }
735
0
    if (i == 0)
736
0
        i = a_len;
737
0
    return equal_case(a, i, b, i, 0);
738
0
}
739
740
/*
741
 * Compare the prefix and suffix with the subject, and check that the
742
 * characters in-between are valid.
743
 */
744
static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
745
                          const unsigned char *suffix, size_t suffix_len,
746
                          const unsigned char *subject, size_t subject_len,
747
                          unsigned int flags)
748
0
{
749
0
    const unsigned char *wildcard_start;
750
0
    const unsigned char *wildcard_end;
751
0
    const unsigned char *p;
752
0
    int allow_multi = 0;
753
0
    int allow_idna = 0;
754
755
0
    if (subject_len < prefix_len + suffix_len)
756
0
        return 0;
757
0
    if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
758
0
        return 0;
759
0
    wildcard_start = subject + prefix_len;
760
0
    wildcard_end = subject + (subject_len - suffix_len);
761
0
    if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
762
0
        return 0;
763
    /*
764
     * If the wildcard makes up the entire first label, it must match at
765
     * least one character.
766
     */
767
0
    if (prefix_len == 0 && *suffix == '.') {
768
0
        if (wildcard_start == wildcard_end)
769
0
            return 0;
770
0
        allow_idna = 1;
771
0
        if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
772
0
            allow_multi = 1;
773
0
    }
774
    /* IDNA labels cannot match partial wildcards */
775
0
    if (!allow_idna &&
776
0
        subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0)
777
0
        return 0;
778
    /* The wildcard may match a literal '*' */
779
0
    if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
780
0
        return 1;
781
    /*
782
     * Check that the part matched by the wildcard contains only
783
     * permitted characters and only matches a single label unless
784
     * allow_multi is set.
785
     */
786
0
    for (p = wildcard_start; p != wildcard_end; ++p)
787
0
        if (!(('0' <= *p && *p <= '9') ||
788
0
              ('A' <= *p && *p <= 'Z') ||
789
0
              ('a' <= *p && *p <= 'z') ||
790
0
              *p == '-' || (allow_multi && *p == '.')))
791
0
            return 0;
792
0
    return 1;
793
0
}
794
795
0
#define LABEL_START     (1 << 0)
796
#define LABEL_END       (1 << 1)
797
0
#define LABEL_HYPHEN    (1 << 2)
798
0
#define LABEL_IDNA      (1 << 3)
799
800
static const unsigned char *valid_star(const unsigned char *p, size_t len,
801
                                       unsigned int flags)
802
0
{
803
0
    const unsigned char *star = 0;
804
0
    size_t i;
805
0
    int state = LABEL_START;
806
0
    int dots = 0;
807
0
    for (i = 0; i < len; ++i) {
808
        /*
809
         * Locate first and only legal wildcard, either at the start
810
         * or end of a non-IDNA first and not final label.
811
         */
812
0
        if (p[i] == '*') {
813
0
            int atstart = (state & LABEL_START);
814
0
            int atend = (i == len - 1 || p[i + 1] == '.');
815
            /*-
816
             * At most one wildcard per pattern.
817
             * No wildcards in IDNA labels.
818
             * No wildcards after the first label.
819
             */
820
0
            if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
821
0
                return NULL;
822
            /* Only full-label '*.example.com' wildcards? */
823
0
            if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
824
0
                && (!atstart || !atend))
825
0
                return NULL;
826
            /* No 'foo*bar' wildcards */
827
0
            if (!atstart && !atend)
828
0
                return NULL;
829
0
            star = &p[i];
830
0
            state &= ~LABEL_START;
831
0
        } else if (('a' <= p[i] && p[i] <= 'z')
832
0
                   || ('A' <= p[i] && p[i] <= 'Z')
833
0
                   || ('0' <= p[i] && p[i] <= '9')) {
834
0
            if ((state & LABEL_START) != 0
835
0
                && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0)
836
0
                state |= LABEL_IDNA;
837
0
            state &= ~(LABEL_HYPHEN | LABEL_START);
838
0
        } else if (p[i] == '.') {
839
0
            if ((state & (LABEL_HYPHEN | LABEL_START)) != 0)
840
0
                return NULL;
841
0
            state = LABEL_START;
842
0
            ++dots;
843
0
        } else if (p[i] == '-') {
844
            /* no domain/subdomain starts with '-' */
845
0
            if ((state & LABEL_START) != 0)
846
0
                return NULL;
847
0
            state |= LABEL_HYPHEN;
848
0
        } else
849
0
            return NULL;
850
0
    }
851
852
    /*
853
     * The final label must not end in a hyphen or ".", and
854
     * there must be at least two dots after the star.
855
     */
856
0
    if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
857
0
        return NULL;
858
0
    return star;
859
0
}
860
861
/* Compare using wildcards. */
862
static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
863
                          const unsigned char *subject, size_t subject_len,
864
                          unsigned int flags)
865
0
{
866
0
    const unsigned char *star = NULL;
867
868
    /*
869
     * Subject names starting with '.' can only match a wildcard pattern
870
     * via a subject sub-domain pattern suffix match.
871
     */
872
0
    if (!(subject_len > 1 && subject[0] == '.'))
873
0
        star = valid_star(pattern, pattern_len, flags);
874
0
    if (star == NULL)
875
0
        return equal_nocase(pattern, pattern_len,
876
0
                            subject, subject_len, flags);
877
0
    return wildcard_match(pattern, star - pattern,
878
0
                          star + 1, (pattern + pattern_len) - star - 1,
879
0
                          subject, subject_len, flags);
880
0
}
881
882
/*
883
 * Compare an ASN1_STRING to a supplied string. If they match return 1. If
884
 * cmp_type > 0 only compare if string matches the type, otherwise convert it
885
 * to UTF8.
886
 */
887
888
static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal,
889
                           unsigned int flags, const char *b, size_t blen,
890
                           char **peername)
891
0
{
892
0
    int rv = 0;
893
894
0
    if (!a->data || !a->length)
895
0
        return 0;
896
0
    if (cmp_type > 0) {
897
0
        if (cmp_type != a->type)
898
0
            return 0;
899
0
        if (cmp_type == V_ASN1_IA5STRING)
900
0
            rv = equal(a->data, a->length, (unsigned char *)b, blen, flags);
901
0
        else if (a->length == (int)blen && !memcmp(a->data, b, blen))
902
0
            rv = 1;
903
0
        if (rv > 0 && peername)
904
0
            *peername = BUF_strndup((char *)a->data, a->length);
905
0
    } else {
906
0
        int astrlen;
907
0
        unsigned char *astr;
908
0
        astrlen = ASN1_STRING_to_UTF8(&astr, a);
909
0
        if (astrlen < 0) {
910
            /*
911
             * -1 could be an internal malloc failure or a decoding error from
912
             * malformed input; we can't distinguish.
913
             */
914
0
            return -1;
915
0
        }
916
0
        rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
917
0
        if (rv > 0 && peername)
918
0
            *peername = BUF_strndup((char *)astr, astrlen);
919
0
        OPENSSL_free(astr);
920
0
    }
921
0
    return rv;
922
0
}
923
924
static int do_x509_check(X509 *x, const char *chk, size_t chklen,
925
                         unsigned int flags, int check_type, char **peername)
926
0
{
927
0
    GENERAL_NAMES *gens = NULL;
928
0
    X509_NAME *name = NULL;
929
0
    int i;
930
0
    int cnid = NID_undef;
931
0
    int alt_type;
932
0
    int san_present = 0;
933
0
    int rv = 0;
934
0
    equal_fn equal;
935
936
    /* See below, this flag is internal-only */
937
0
    flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
938
0
    if (check_type == GEN_EMAIL) {
939
0
        cnid = NID_pkcs9_emailAddress;
940
0
        alt_type = V_ASN1_IA5STRING;
941
0
        equal = equal_email;
942
0
    } else if (check_type == GEN_DNS) {
943
0
        cnid = NID_commonName;
944
        /* Implicit client-side DNS sub-domain pattern */
945
0
        if (chklen > 1 && chk[0] == '.')
946
0
            flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
947
0
        alt_type = V_ASN1_IA5STRING;
948
0
        if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
949
0
            equal = equal_nocase;
950
0
        else
951
0
            equal = equal_wildcard;
952
0
    } else {
953
0
        alt_type = V_ASN1_OCTET_STRING;
954
0
        equal = equal_case;
955
0
    }
956
957
0
    if (chklen == 0)
958
0
        chklen = strlen(chk);
959
960
0
    gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
961
0
    if (gens) {
962
0
        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
963
0
            GENERAL_NAME *gen;
964
0
            ASN1_STRING *cstr;
965
0
            gen = sk_GENERAL_NAME_value(gens, i);
966
0
            if (gen->type != check_type)
967
0
                continue;
968
0
            san_present = 1;
969
0
            if (check_type == GEN_EMAIL)
970
0
                cstr = gen->d.rfc822Name;
971
0
            else if (check_type == GEN_DNS)
972
0
                cstr = gen->d.dNSName;
973
0
            else
974
0
                cstr = gen->d.iPAddress;
975
            /* Positive on success, negative on error! */
976
0
            if ((rv = do_check_string(cstr, alt_type, equal, flags,
977
0
                                      chk, chklen, peername)) != 0)
978
0
                break;
979
0
        }
980
0
        GENERAL_NAMES_free(gens);
981
0
        if (rv != 0)
982
0
            return rv;
983
0
        if (cnid == NID_undef
984
0
            || (san_present
985
0
                && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)))
986
0
            return 0;
987
0
    }
988
989
    /* We're done if CN-ID is not pertinent */
990
0
    if (cnid == NID_undef)
991
0
        return 0;
992
993
0
    i = -1;
994
0
    name = X509_get_subject_name(x);
995
0
    while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) {
996
0
        X509_NAME_ENTRY *ne;
997
0
        ASN1_STRING *str;
998
0
        ne = X509_NAME_get_entry(name, i);
999
0
        str = X509_NAME_ENTRY_get_data(ne);
1000
        /* Positive on success, negative on error! */
1001
0
        if ((rv = do_check_string(str, -1, equal, flags,
1002
0
                                  chk, chklen, peername)) != 0)
1003
0
            return rv;
1004
0
    }
1005
0
    return 0;
1006
0
}
1007
1008
int X509_check_host(X509 *x, const char *chk, size_t chklen,
1009
                    unsigned int flags, char **peername)
1010
0
{
1011
0
    if (chk == NULL)
1012
0
        return -2;
1013
    /*
1014
     * Embedded NULs are disallowed, except as the last character of a
1015
     * string of length 2 or more (tolerate caller including terminating
1016
     * NUL in string length).
1017
     */
1018
0
    if (chklen == 0)
1019
0
        chklen = strlen(chk);
1020
0
    else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
1021
0
        return -2;
1022
0
    if (chklen > 1 && chk[chklen - 1] == '\0')
1023
0
        --chklen;
1024
0
    return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
1025
0
}
1026
1027
int X509_check_email(X509 *x, const char *chk, size_t chklen,
1028
                     unsigned int flags)
1029
0
{
1030
0
    if (chk == NULL)
1031
0
        return -2;
1032
    /*
1033
     * Embedded NULs are disallowed, except as the last character of a
1034
     * string of length 2 or more (tolerate caller including terminating
1035
     * NUL in string length).
1036
     */
1037
0
    if (chklen == 0)
1038
0
        chklen = strlen((char *)chk);
1039
0
    else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
1040
0
        return -2;
1041
0
    if (chklen > 1 && chk[chklen - 1] == '\0')
1042
0
        --chklen;
1043
0
    return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
1044
0
}
1045
1046
int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
1047
                  unsigned int flags)
1048
0
{
1049
0
    if (chk == NULL)
1050
0
        return -2;
1051
0
    return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
1052
0
}
1053
1054
int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
1055
0
{
1056
0
    unsigned char ipout[16];
1057
0
    size_t iplen;
1058
1059
0
    if (ipasc == NULL)
1060
0
        return -2;
1061
0
    iplen = (size_t)a2i_ipadd(ipout, ipasc);
1062
0
    if (iplen == 0)
1063
0
        return -2;
1064
0
    return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
1065
0
}
1066
1067
/*
1068
 * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
1069
 * with RFC3280.
1070
 */
1071
1072
ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
1073
0
{
1074
0
    unsigned char ipout[16];
1075
0
    ASN1_OCTET_STRING *ret;
1076
0
    int iplen;
1077
1078
    /* If string contains a ':' assume IPv6 */
1079
1080
0
    iplen = a2i_ipadd(ipout, ipasc);
1081
1082
0
    if (!iplen)
1083
0
        return NULL;
1084
1085
0
    ret = ASN1_OCTET_STRING_new();
1086
0
    if (!ret)
1087
0
        return NULL;
1088
0
    if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
1089
0
        ASN1_OCTET_STRING_free(ret);
1090
0
        return NULL;
1091
0
    }
1092
0
    return ret;
1093
0
}
1094
1095
ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
1096
0
{
1097
0
    ASN1_OCTET_STRING *ret = NULL;
1098
0
    unsigned char ipout[32];
1099
0
    char *iptmp = NULL, *p;
1100
0
    int iplen1, iplen2;
1101
0
    p = strchr(ipasc, '/');
1102
0
    if (!p)
1103
0
        return NULL;
1104
0
    iptmp = BUF_strdup(ipasc);
1105
0
    if (!iptmp)
1106
0
        return NULL;
1107
0
    p = iptmp + (p - ipasc);
1108
0
    *p++ = 0;
1109
1110
0
    iplen1 = a2i_ipadd(ipout, iptmp);
1111
1112
0
    if (!iplen1)
1113
0
        goto err;
1114
1115
0
    iplen2 = a2i_ipadd(ipout + iplen1, p);
1116
1117
0
    OPENSSL_free(iptmp);
1118
0
    iptmp = NULL;
1119
1120
0
    if (!iplen2 || (iplen1 != iplen2))
1121
0
        goto err;
1122
1123
0
    ret = ASN1_OCTET_STRING_new();
1124
0
    if (!ret)
1125
0
        goto err;
1126
0
    if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
1127
0
        goto err;
1128
1129
0
    return ret;
1130
1131
0
 err:
1132
0
    if (iptmp)
1133
0
        OPENSSL_free(iptmp);
1134
0
    if (ret)
1135
0
        ASN1_OCTET_STRING_free(ret);
1136
0
    return NULL;
1137
0
}
1138
1139
int a2i_ipadd(unsigned char *ipout, const char *ipasc)
1140
0
{
1141
    /* If string contains a ':' assume IPv6 */
1142
1143
0
    if (strchr(ipasc, ':')) {
1144
0
        if (!ipv6_from_asc(ipout, ipasc))
1145
0
            return 0;
1146
0
        return 16;
1147
0
    } else {
1148
0
        if (!ipv4_from_asc(ipout, ipasc))
1149
0
            return 0;
1150
0
        return 4;
1151
0
    }
1152
0
}
1153
1154
static int ipv4_from_asc(unsigned char *v4, const char *in)
1155
0
{
1156
0
    int a0, a1, a2, a3;
1157
0
    if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
1158
0
        return 0;
1159
0
    if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
1160
0
        || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
1161
0
        return 0;
1162
0
    v4[0] = a0;
1163
0
    v4[1] = a1;
1164
0
    v4[2] = a2;
1165
0
    v4[3] = a3;
1166
0
    return 1;
1167
0
}
1168
1169
typedef struct {
1170
    /* Temporary store for IPV6 output */
1171
    unsigned char tmp[16];
1172
    /* Total number of bytes in tmp */
1173
    int total;
1174
    /* The position of a zero (corresponding to '::') */
1175
    int zero_pos;
1176
    /* Number of zeroes */
1177
    int zero_cnt;
1178
} IPV6_STAT;
1179
1180
static int ipv6_from_asc(unsigned char *v6, const char *in)
1181
0
{
1182
0
    IPV6_STAT v6stat;
1183
0
    v6stat.total = 0;
1184
0
    v6stat.zero_pos = -1;
1185
0
    v6stat.zero_cnt = 0;
1186
    /*
1187
     * Treat the IPv6 representation as a list of values separated by ':'.
1188
     * The presence of a '::' will parse as one, two or three zero length
1189
     * elements.
1190
     */
1191
0
    if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
1192
0
        return 0;
1193
1194
    /* Now for some sanity checks */
1195
1196
0
    if (v6stat.zero_pos == -1) {
1197
        /* If no '::' must have exactly 16 bytes */
1198
0
        if (v6stat.total != 16)
1199
0
            return 0;
1200
0
    } else {
1201
        /* If '::' must have less than 16 bytes */
1202
0
        if (v6stat.total == 16)
1203
0
            return 0;
1204
        /* More than three zeroes is an error */
1205
0
        if (v6stat.zero_cnt > 3)
1206
0
            return 0;
1207
        /* Can only have three zeroes if nothing else present */
1208
0
        else if (v6stat.zero_cnt == 3) {
1209
0
            if (v6stat.total > 0)
1210
0
                return 0;
1211
0
        }
1212
        /* Can only have two zeroes if at start or end */
1213
0
        else if (v6stat.zero_cnt == 2) {
1214
0
            if ((v6stat.zero_pos != 0)
1215
0
                && (v6stat.zero_pos != v6stat.total))
1216
0
                return 0;
1217
0
        } else
1218
            /* Can only have one zero if *not* start or end */
1219
0
        {
1220
0
            if ((v6stat.zero_pos == 0)
1221
0
                || (v6stat.zero_pos == v6stat.total))
1222
0
                return 0;
1223
0
        }
1224
0
    }
1225
1226
    /* Format result */
1227
1228
0
    if (v6stat.zero_pos >= 0) {
1229
        /* Copy initial part */
1230
0
        memcpy(v6, v6stat.tmp, v6stat.zero_pos);
1231
        /* Zero middle */
1232
0
        memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
1233
        /* Copy final part */
1234
0
        if (v6stat.total != v6stat.zero_pos)
1235
0
            memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
1236
0
                   v6stat.tmp + v6stat.zero_pos,
1237
0
                   v6stat.total - v6stat.zero_pos);
1238
0
    } else
1239
0
        memcpy(v6, v6stat.tmp, 16);
1240
1241
0
    return 1;
1242
0
}
1243
1244
static int ipv6_cb(const char *elem, int len, void *usr)
1245
0
{
1246
0
    IPV6_STAT *s = usr;
1247
    /* Error if 16 bytes written */
1248
0
    if (s->total == 16)
1249
0
        return 0;
1250
0
    if (len == 0) {
1251
        /* Zero length element, corresponds to '::' */
1252
0
        if (s->zero_pos == -1)
1253
0
            s->zero_pos = s->total;
1254
        /* If we've already got a :: its an error */
1255
0
        else if (s->zero_pos != s->total)
1256
0
            return 0;
1257
0
        s->zero_cnt++;
1258
0
    } else {
1259
        /* If more than 4 characters could be final a.b.c.d form */
1260
0
        if (len > 4) {
1261
            /* Need at least 4 bytes left */
1262
0
            if (s->total > 12)
1263
0
                return 0;
1264
            /* Must be end of string */
1265
0
            if (elem[len])
1266
0
                return 0;
1267
0
            if (!ipv4_from_asc(s->tmp + s->total, elem))
1268
0
                return 0;
1269
0
            s->total += 4;
1270
0
        } else {
1271
0
            if (!ipv6_hex(s->tmp + s->total, elem, len))
1272
0
                return 0;
1273
0
            s->total += 2;
1274
0
        }
1275
0
    }
1276
0
    return 1;
1277
0
}
1278
1279
/*
1280
 * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
1281
 */
1282
1283
static int ipv6_hex(unsigned char *out, const char *in, int inlen)
1284
0
{
1285
0
    unsigned char c;
1286
0
    unsigned int num = 0;
1287
0
    if (inlen > 4)
1288
0
        return 0;
1289
0
    while (inlen--) {
1290
0
        c = *in++;
1291
0
        num <<= 4;
1292
0
        if ((c >= '0') && (c <= '9'))
1293
0
            num |= c - '0';
1294
0
        else if ((c >= 'A') && (c <= 'F'))
1295
0
            num |= c - 'A' + 10;
1296
0
        else if ((c >= 'a') && (c <= 'f'))
1297
0
            num |= c - 'a' + 10;
1298
0
        else
1299
0
            return 0;
1300
0
    }
1301
0
    out[0] = num >> 8;
1302
0
    out[1] = num & 0xff;
1303
0
    return 1;
1304
0
}
1305
1306
int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
1307
                             unsigned long chtype)
1308
0
{
1309
0
    CONF_VALUE *v;
1310
0
    int i, mval;
1311
0
    char *p, *type;
1312
0
    if (!nm)
1313
0
        return 0;
1314
1315
0
    for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1316
0
        v = sk_CONF_VALUE_value(dn_sk, i);
1317
0
        type = v->name;
1318
        /*
1319
         * Skip past any leading X. X: X, etc to allow for multiple instances
1320
         */
1321
0
        for (p = type; *p; p++)
1322
0
#ifndef CHARSET_EBCDIC
1323
0
            if ((*p == ':') || (*p == ',') || (*p == '.'))
1324
#else
1325
            if ((*p == os_toascii[':']) || (*p == os_toascii[','])
1326
                || (*p == os_toascii['.']))
1327
#endif
1328
0
            {
1329
0
                p++;
1330
0
                if (*p)
1331
0
                    type = p;
1332
0
                break;
1333
0
            }
1334
0
#ifndef CHARSET_EBCDIC
1335
0
        if (*type == '+')
1336
#else
1337
        if (*type == os_toascii['+'])
1338
#endif
1339
0
        {
1340
0
            mval = -1;
1341
0
            type++;
1342
0
        } else
1343
0
            mval = 0;
1344
0
        if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
1345
0
                                        (unsigned char *)v->value, -1, -1,
1346
0
                                        mval))
1347
0
            return 0;
1348
1349
0
    }
1350
0
    return 1;
1351
0
}