Coverage Report

Created: 2023-06-08 06:40

/src/openssl111/crypto/x509v3/v3_alt.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1999-2021 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
#include "internal/cryptlib.h"
12
#include "crypto/x509.h"
13
#include <openssl/conf.h>
14
#include <openssl/x509v3.h>
15
#include "ext_dat.h"
16
17
static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
18
                                      X509V3_CTX *ctx,
19
                                      STACK_OF(CONF_VALUE) *nval);
20
static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
21
                                     X509V3_CTX *ctx,
22
                                     STACK_OF(CONF_VALUE) *nval);
23
static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
24
static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
25
static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
26
static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
27
28
const X509V3_EXT_METHOD v3_alt[3] = {
29
    {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
30
     0, 0, 0, 0,
31
     0, 0,
32
     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
33
     (X509V3_EXT_V2I)v2i_subject_alt,
34
     NULL, NULL, NULL},
35
36
    {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
37
     0, 0, 0, 0,
38
     0, 0,
39
     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
40
     (X509V3_EXT_V2I)v2i_issuer_alt,
41
     NULL, NULL, NULL},
42
43
    {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
44
     0, 0, 0, 0,
45
     0, 0,
46
     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
47
     NULL, NULL, NULL, NULL},
48
};
49
50
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
51
                                        GENERAL_NAMES *gens,
52
                                        STACK_OF(CONF_VALUE) *ret)
53
0
{
54
0
    int i;
55
0
    GENERAL_NAME *gen;
56
0
    STACK_OF(CONF_VALUE) *tmpret = NULL, *origret = ret;
57
58
0
    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
59
0
        gen = sk_GENERAL_NAME_value(gens, i);
60
        /*
61
         * i2v_GENERAL_NAME allocates ret if it is NULL. If something goes
62
         * wrong we need to free the stack - but only if it was empty when we
63
         * originally entered this function.
64
         */
65
0
        tmpret = i2v_GENERAL_NAME(method, gen, ret);
66
0
        if (tmpret == NULL) {
67
0
            if (origret == NULL)
68
0
                sk_CONF_VALUE_pop_free(ret, X509V3_conf_free);
69
0
            return NULL;
70
0
        }
71
0
        ret = tmpret;
72
0
    }
73
0
    if (ret == NULL)
74
0
        return sk_CONF_VALUE_new_null();
75
0
    return ret;
76
0
}
77
78
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
79
                                       GENERAL_NAME *gen,
80
                                       STACK_OF(CONF_VALUE) *ret)
81
0
{
82
0
    unsigned char *p;
83
0
    char oline[256], htmp[5];
84
0
    int i;
85
86
0
    switch (gen->type) {
87
0
    case GEN_OTHERNAME:
88
0
        if (!X509V3_add_value("othername", "<unsupported>", &ret))
89
0
            return NULL;
90
0
        break;
91
92
0
    case GEN_X400:
93
0
        if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
94
0
            return NULL;
95
0
        break;
96
97
0
    case GEN_EDIPARTY:
98
0
        if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret))
99
0
            return NULL;
100
0
        break;
101
102
0
    case GEN_EMAIL:
103
0
        if (!x509v3_add_len_value_uchar("email", gen->d.ia5->data,
104
0
                                        gen->d.ia5->length, &ret))
105
0
            return NULL;
106
0
        break;
107
108
0
    case GEN_DNS:
109
0
        if (!x509v3_add_len_value_uchar("DNS", gen->d.ia5->data,
110
0
                                        gen->d.ia5->length, &ret))
111
0
            return NULL;
112
0
        break;
113
114
0
    case GEN_URI:
115
0
        if (!x509v3_add_len_value_uchar("URI", gen->d.ia5->data,
116
0
                                        gen->d.ia5->length, &ret))
117
0
            return NULL;
118
0
        break;
119
120
0
    case GEN_DIRNAME:
121
0
        if (X509_NAME_oneline(gen->d.dirn, oline, sizeof(oline)) == NULL
122
0
                || !X509V3_add_value("DirName", oline, &ret))
123
0
            return NULL;
124
0
        break;
125
126
0
    case GEN_IPADD:
127
0
        p = gen->d.ip->data;
128
0
        if (gen->d.ip->length == 4)
129
0
            BIO_snprintf(oline, sizeof(oline), "%d.%d.%d.%d",
130
0
                         p[0], p[1], p[2], p[3]);
131
0
        else if (gen->d.ip->length == 16) {
132
0
            oline[0] = 0;
133
0
            for (i = 0; i < 8; i++) {
134
0
                BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]);
135
0
                p += 2;
136
0
                strcat(oline, htmp);
137
0
                if (i != 7)
138
0
                    strcat(oline, ":");
139
0
            }
140
0
        } else {
141
0
            if (!X509V3_add_value("IP Address", "<invalid>", &ret))
142
0
                return NULL;
143
0
            break;
144
0
        }
145
0
        if (!X509V3_add_value("IP Address", oline, &ret))
146
0
            return NULL;
147
0
        break;
148
149
0
    case GEN_RID:
150
0
        i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
151
0
        if (!X509V3_add_value("Registered ID", oline, &ret))
152
0
            return NULL;
153
0
        break;
154
0
    }
155
0
    return ret;
156
0
}
157
158
int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
159
0
{
160
0
    unsigned char *p;
161
0
    int i;
162
0
    switch (gen->type) {
163
0
    case GEN_OTHERNAME:
164
0
        BIO_printf(out, "othername:<unsupported>");
165
0
        break;
166
167
0
    case GEN_X400:
168
0
        BIO_printf(out, "X400Name:<unsupported>");
169
0
        break;
170
171
0
    case GEN_EDIPARTY:
172
        /* Maybe fix this: it is supported now */
173
0
        BIO_printf(out, "EdiPartyName:<unsupported>");
174
0
        break;
175
176
0
    case GEN_EMAIL:
177
0
        BIO_printf(out, "email:");
178
0
        ASN1_STRING_print(out, gen->d.ia5);
179
0
        break;
180
181
0
    case GEN_DNS:
182
0
        BIO_printf(out, "DNS:");
183
0
        ASN1_STRING_print(out, gen->d.ia5);
184
0
        break;
185
186
0
    case GEN_URI:
187
0
        BIO_printf(out, "URI:");
188
0
        ASN1_STRING_print(out, gen->d.ia5);
189
0
        break;
190
191
0
    case GEN_DIRNAME:
192
0
        BIO_printf(out, "DirName:");
193
0
        X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
194
0
        break;
195
196
0
    case GEN_IPADD:
197
0
        p = gen->d.ip->data;
198
0
        if (gen->d.ip->length == 4)
199
0
            BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
200
0
        else if (gen->d.ip->length == 16) {
201
0
            BIO_printf(out, "IP Address");
202
0
            for (i = 0; i < 8; i++) {
203
0
                BIO_printf(out, ":%X", p[0] << 8 | p[1]);
204
0
                p += 2;
205
0
            }
206
0
            BIO_puts(out, "\n");
207
0
        } else {
208
0
            BIO_printf(out, "IP Address:<invalid>");
209
0
            break;
210
0
        }
211
0
        break;
212
213
0
    case GEN_RID:
214
0
        BIO_printf(out, "Registered ID:");
215
0
        i2a_ASN1_OBJECT(out, gen->d.rid);
216
0
        break;
217
0
    }
218
0
    return 1;
219
0
}
220
221
static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
222
                                     X509V3_CTX *ctx,
223
                                     STACK_OF(CONF_VALUE) *nval)
224
0
{
225
0
    const int num = sk_CONF_VALUE_num(nval);
226
0
    GENERAL_NAMES *gens = sk_GENERAL_NAME_new_reserve(NULL, num);
227
0
    int i;
228
229
0
    if (gens == NULL) {
230
0
        X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE);
231
0
        sk_GENERAL_NAME_free(gens);
232
0
        return NULL;
233
0
    }
234
0
    for (i = 0; i < num; i++) {
235
0
        CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
236
237
0
        if (!name_cmp(cnf->name, "issuer")
238
0
            && cnf->value && strcmp(cnf->value, "copy") == 0) {
239
0
            if (!copy_issuer(ctx, gens))
240
0
                goto err;
241
0
        } else {
242
0
            GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
243
244
0
            if (gen == NULL)
245
0
                goto err;
246
0
            sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */
247
0
        }
248
0
    }
249
0
    return gens;
250
0
 err:
251
0
    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
252
0
    return NULL;
253
0
}
254
255
/* Append subject altname of issuer to issuer alt name of subject */
256
257
static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
258
0
{
259
0
    GENERAL_NAMES *ialt;
260
0
    GENERAL_NAME *gen;
261
0
    X509_EXTENSION *ext;
262
0
    int i, num;
263
264
0
    if (ctx && (ctx->flags == CTX_TEST))
265
0
        return 1;
266
0
    if (!ctx || !ctx->issuer_cert) {
267
0
        X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS);
268
0
        goto err;
269
0
    }
270
0
    i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
271
0
    if (i < 0)
272
0
        return 1;
273
0
    if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL
274
0
        || (ialt = X509V3_EXT_d2i(ext)) == NULL) {
275
0
        X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR);
276
0
        goto err;
277
0
    }
278
279
0
    num = sk_GENERAL_NAME_num(ialt);
280
0
    if (!sk_GENERAL_NAME_reserve(gens, num)) {
281
0
        X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE);
282
0
        sk_GENERAL_NAME_free(ialt);
283
0
        goto err;
284
0
    }
285
286
0
    for (i = 0; i < num; i++) {
287
0
        gen = sk_GENERAL_NAME_value(ialt, i);
288
0
        sk_GENERAL_NAME_push(gens, gen);     /* no failure as it was reserved */
289
0
    }
290
0
    sk_GENERAL_NAME_free(ialt);
291
292
0
    return 1;
293
294
0
 err:
295
0
    return 0;
296
297
0
}
298
299
static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
300
                                      X509V3_CTX *ctx,
301
                                      STACK_OF(CONF_VALUE) *nval)
302
0
{
303
0
    GENERAL_NAMES *gens;
304
0
    CONF_VALUE *cnf;
305
0
    const int num = sk_CONF_VALUE_num(nval);
306
0
    int i;
307
308
0
    gens = sk_GENERAL_NAME_new_reserve(NULL, num);
309
0
    if (gens == NULL) {
310
0
        X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE);
311
0
        sk_GENERAL_NAME_free(gens);
312
0
        return NULL;
313
0
    }
314
315
0
    for (i = 0; i < num; i++) {
316
0
        cnf = sk_CONF_VALUE_value(nval, i);
317
0
        if (!name_cmp(cnf->name, "email")
318
0
            && cnf->value && strcmp(cnf->value, "copy") == 0) {
319
0
            if (!copy_email(ctx, gens, 0))
320
0
                goto err;
321
0
        } else if (!name_cmp(cnf->name, "email")
322
0
                   && cnf->value && strcmp(cnf->value, "move") == 0) {
323
0
            if (!copy_email(ctx, gens, 1))
324
0
                goto err;
325
0
        } else {
326
0
            GENERAL_NAME *gen;
327
0
            if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
328
0
                goto err;
329
0
            sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */
330
0
        }
331
0
    }
332
0
    return gens;
333
0
 err:
334
0
    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
335
0
    return NULL;
336
0
}
337
338
/*
339
 * Copy any email addresses in a certificate or request to GENERAL_NAMES
340
 */
341
342
static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
343
0
{
344
0
    X509_NAME *nm;
345
0
    ASN1_IA5STRING *email = NULL;
346
0
    X509_NAME_ENTRY *ne;
347
0
    GENERAL_NAME *gen = NULL;
348
0
    int i = -1;
349
350
0
    if (ctx != NULL && ctx->flags == CTX_TEST)
351
0
        return 1;
352
0
    if (ctx == NULL
353
0
        || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) {
354
0
        X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS);
355
0
        goto err;
356
0
    }
357
    /* Find the subject name */
358
0
    if (ctx->subject_cert)
359
0
        nm = X509_get_subject_name(ctx->subject_cert);
360
0
    else
361
0
        nm = X509_REQ_get_subject_name(ctx->subject_req);
362
363
    /* Now add any email address(es) to STACK */
364
0
    while ((i = X509_NAME_get_index_by_NID(nm,
365
0
                                           NID_pkcs9_emailAddress, i)) >= 0) {
366
0
        ne = X509_NAME_get_entry(nm, i);
367
0
        email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
368
0
        if (move_p) {
369
0
            X509_NAME_delete_entry(nm, i);
370
0
            X509_NAME_ENTRY_free(ne);
371
0
            i--;
372
0
        }
373
0
        if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) {
374
0
            X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
375
0
            goto err;
376
0
        }
377
0
        gen->d.ia5 = email;
378
0
        email = NULL;
379
0
        gen->type = GEN_EMAIL;
380
0
        if (!sk_GENERAL_NAME_push(gens, gen)) {
381
0
            X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
382
0
            goto err;
383
0
        }
384
0
        gen = NULL;
385
0
    }
386
387
0
    return 1;
388
389
0
 err:
390
0
    GENERAL_NAME_free(gen);
391
0
    ASN1_IA5STRING_free(email);
392
0
    return 0;
393
394
0
}
395
396
GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
397
                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
398
0
{
399
0
    GENERAL_NAME *gen;
400
0
    GENERAL_NAMES *gens;
401
0
    CONF_VALUE *cnf;
402
0
    const int num = sk_CONF_VALUE_num(nval);
403
0
    int i;
404
405
0
    gens = sk_GENERAL_NAME_new_reserve(NULL, num);
406
0
    if (gens == NULL) {
407
0
        X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
408
0
        sk_GENERAL_NAME_free(gens);
409
0
        return NULL;
410
0
    }
411
412
0
    for (i = 0; i < num; i++) {
413
0
        cnf = sk_CONF_VALUE_value(nval, i);
414
0
        if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
415
0
            goto err;
416
0
        sk_GENERAL_NAME_push(gens, gen);    /* no failure as it was reserved */
417
0
    }
418
0
    return gens;
419
0
 err:
420
0
    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
421
0
    return NULL;
422
0
}
423
424
GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
425
                               X509V3_CTX *ctx, CONF_VALUE *cnf)
426
0
{
427
0
    return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
428
0
}
429
430
GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
431
                               const X509V3_EXT_METHOD *method,
432
                               X509V3_CTX *ctx, int gen_type, const char *value,
433
                               int is_nc)
434
0
{
435
0
    char is_string = 0;
436
0
    GENERAL_NAME *gen = NULL;
437
438
0
    if (!value) {
439
0
        X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE);
440
0
        return NULL;
441
0
    }
442
443
0
    if (out)
444
0
        gen = out;
445
0
    else {
446
0
        gen = GENERAL_NAME_new();
447
0
        if (gen == NULL) {
448
0
            X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
449
0
            return NULL;
450
0
        }
451
0
    }
452
453
0
    switch (gen_type) {
454
0
    case GEN_URI:
455
0
    case GEN_EMAIL:
456
0
    case GEN_DNS:
457
0
        is_string = 1;
458
0
        break;
459
460
0
    case GEN_RID:
461
0
        {
462
0
            ASN1_OBJECT *obj;
463
0
            if ((obj = OBJ_txt2obj(value, 0)) == NULL) {
464
0
                X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT);
465
0
                ERR_add_error_data(2, "value=", value);
466
0
                goto err;
467
0
            }
468
0
            gen->d.rid = obj;
469
0
        }
470
0
        break;
471
472
0
    case GEN_IPADD:
473
0
        if (is_nc)
474
0
            gen->d.ip = a2i_IPADDRESS_NC(value);
475
0
        else
476
0
            gen->d.ip = a2i_IPADDRESS(value);
477
0
        if (gen->d.ip == NULL) {
478
0
            X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS);
479
0
            ERR_add_error_data(2, "value=", value);
480
0
            goto err;
481
0
        }
482
0
        break;
483
484
0
    case GEN_DIRNAME:
485
0
        if (!do_dirname(gen, value, ctx)) {
486
0
            X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR);
487
0
            goto err;
488
0
        }
489
0
        break;
490
491
0
    case GEN_OTHERNAME:
492
0
        if (!do_othername(gen, value, ctx)) {
493
0
            X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR);
494
0
            goto err;
495
0
        }
496
0
        break;
497
0
    default:
498
0
        X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE);
499
0
        goto err;
500
0
    }
501
502
0
    if (is_string) {
503
0
        if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL ||
504
0
            !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
505
0
                             strlen(value))) {
506
0
            X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
507
0
            goto err;
508
0
        }
509
0
    }
510
511
0
    gen->type = gen_type;
512
513
0
    return gen;
514
515
0
 err:
516
0
    if (!out)
517
0
        GENERAL_NAME_free(gen);
518
0
    return NULL;
519
0
}
520
521
GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
522
                                  const X509V3_EXT_METHOD *method,
523
                                  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
524
0
{
525
0
    int type;
526
527
0
    char *name, *value;
528
529
0
    name = cnf->name;
530
0
    value = cnf->value;
531
532
0
    if (!value) {
533
0
        X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE);
534
0
        return NULL;
535
0
    }
536
537
0
    if (!name_cmp(name, "email"))
538
0
        type = GEN_EMAIL;
539
0
    else if (!name_cmp(name, "URI"))
540
0
        type = GEN_URI;
541
0
    else if (!name_cmp(name, "DNS"))
542
0
        type = GEN_DNS;
543
0
    else if (!name_cmp(name, "RID"))
544
0
        type = GEN_RID;
545
0
    else if (!name_cmp(name, "IP"))
546
0
        type = GEN_IPADD;
547
0
    else if (!name_cmp(name, "dirName"))
548
0
        type = GEN_DIRNAME;
549
0
    else if (!name_cmp(name, "otherName"))
550
0
        type = GEN_OTHERNAME;
551
0
    else {
552
0
        X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION);
553
0
        ERR_add_error_data(2, "name=", name);
554
0
        return NULL;
555
0
    }
556
557
0
    return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
558
559
0
}
560
561
static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
562
0
{
563
0
    char *objtmp = NULL, *p;
564
0
    int objlen;
565
566
0
    if ((p = strchr(value, ';')) == NULL)
567
0
        return 0;
568
0
    if ((gen->d.otherName = OTHERNAME_new()) == NULL)
569
0
        return 0;
570
    /*
571
     * Free this up because we will overwrite it. no need to free type_id
572
     * because it is static
573
     */
574
0
    ASN1_TYPE_free(gen->d.otherName->value);
575
0
    if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL)
576
0
        return 0;
577
0
    objlen = p - value;
578
0
    objtmp = OPENSSL_strndup(value, objlen);
579
0
    if (objtmp == NULL)
580
0
        return 0;
581
0
    gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
582
0
    OPENSSL_free(objtmp);
583
0
    if (!gen->d.otherName->type_id)
584
0
        return 0;
585
0
    return 1;
586
0
}
587
588
static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
589
0
{
590
0
    int ret = 0;
591
0
    STACK_OF(CONF_VALUE) *sk = NULL;
592
0
    X509_NAME *nm;
593
594
0
    if ((nm = X509_NAME_new()) == NULL)
595
0
        goto err;
596
0
    sk = X509V3_get_section(ctx, value);
597
0
    if (!sk) {
598
0
        X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND);
599
0
        ERR_add_error_data(2, "section=", value);
600
0
        goto err;
601
0
    }
602
    /* FIXME: should allow other character types... */
603
0
    ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
604
0
    if (!ret)
605
0
        goto err;
606
0
    gen->d.dirn = nm;
607
608
0
err:
609
0
    if (ret == 0)
610
0
        X509_NAME_free(nm);
611
0
    X509V3_section_free(ctx, sk);
612
0
    return ret;
613
0
}