Coverage Report

Created: 2018-08-29 13:53

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