Coverage Report

Created: 2026-03-19 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/x509/v3_alt.cc
Line
Count
Source
1
// Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <stdio.h>
16
#include <string.h>
17
18
#include <openssl/asn1.h>
19
#include <openssl/conf.h>
20
#include <openssl/err.h>
21
#include <openssl/mem.h>
22
#include <openssl/obj.h>
23
#include <openssl/x509.h>
24
25
#include "internal.h"
26
27
28
using namespace bssl;
29
30
static void *v2i_subject_alt(const X509V3_EXT_METHOD *method,
31
                             const X509V3_CTX *ctx,
32
                             const STACK_OF(CONF_VALUE) *nval);
33
static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method,
34
                            const X509V3_CTX *ctx,
35
                            const STACK_OF(CONF_VALUE) *nval);
36
static int copy_email(const X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
37
static int copy_issuer(const X509V3_CTX *ctx, GENERAL_NAMES *gens);
38
static int do_othername(GENERAL_NAME *gen, const char *value,
39
                        const X509V3_CTX *ctx);
40
static int do_dirname(GENERAL_NAME *gen, const char *value,
41
                      const X509V3_CTX *ctx);
42
43
static STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES_cb(
44
372
    const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) {
45
372
  return i2v_GENERAL_NAMES(method, reinterpret_cast<GENERAL_NAMES *>(ext), ret);
46
372
}
47
48
const X509V3_EXT_METHOD bssl::v3_subject_alt_name = {
49
    NID_subject_alt_name,
50
    0,
51
    ASN1_ITEM_ref(GENERAL_NAMES),
52
    nullptr,
53
    nullptr,
54
    nullptr,
55
    nullptr,
56
    nullptr,
57
    nullptr,
58
    i2v_GENERAL_NAMES_cb,
59
    v2i_subject_alt,
60
    nullptr,
61
    nullptr,
62
    nullptr,
63
};
64
65
const X509V3_EXT_METHOD bssl::v3_issuer_alt_name = {
66
    NID_issuer_alt_name,
67
    0,
68
    ASN1_ITEM_ref(GENERAL_NAMES),
69
    nullptr,
70
    nullptr,
71
    nullptr,
72
    nullptr,
73
    nullptr,
74
    nullptr,
75
    i2v_GENERAL_NAMES_cb,
76
    v2i_issuer_alt,
77
    nullptr,
78
    nullptr,
79
    nullptr,
80
};
81
82
const X509V3_EXT_METHOD bssl::v3_certificate_issuer = {
83
    NID_certificate_issuer,
84
    0,
85
    ASN1_ITEM_ref(GENERAL_NAMES),
86
    nullptr,
87
    nullptr,
88
    nullptr,
89
    nullptr,
90
    nullptr,
91
    nullptr,
92
    i2v_GENERAL_NAMES_cb,
93
    nullptr,
94
    nullptr,
95
    nullptr,
96
    nullptr,
97
};
98
99
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
100
                                        const GENERAL_NAMES *gens,
101
490
                                        STACK_OF(CONF_VALUE) *ret) {
102
490
  int ret_was_null = ret == nullptr;
103
10.2k
  for (size_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
104
9.84k
    const GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
105
9.84k
    STACK_OF(CONF_VALUE) *tmp = i2v_GENERAL_NAME(method, gen, ret);
106
9.84k
    if (tmp == nullptr) {
107
132
      if (ret_was_null) {
108
122
        sk_CONF_VALUE_pop_free(ret, X509V3_conf_free);
109
122
      }
110
132
      return nullptr;
111
132
    }
112
9.71k
    ret = tmp;
113
9.71k
  }
114
358
  if (!ret) {
115
134
    return sk_CONF_VALUE_new_null();
116
134
  }
117
224
  return ret;
118
358
}
119
120
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(const X509V3_EXT_METHOD *method,
121
                                       const GENERAL_NAME *gen,
122
9.91k
                                       STACK_OF(CONF_VALUE) *ret) {
123
  // Note the error-handling for this function relies on there being at most
124
  // one |X509V3_add_value| call. If there were two and the second failed, we
125
  // would need to sometimes free the first call's result.
126
9.91k
  unsigned char *p;
127
9.91k
  char oline[256], htmp[5];
128
9.91k
  int i;
129
9.91k
  switch (gen->type) {
130
155
    case GEN_OTHERNAME:
131
155
      if (!X509V3_add_value("othername", "<unsupported>", &ret)) {
132
0
        return nullptr;
133
0
      }
134
155
      break;
135
136
1.46k
    case GEN_X400:
137
1.46k
      if (!X509V3_add_value("X400Name", "<unsupported>", &ret)) {
138
0
        return nullptr;
139
0
      }
140
1.46k
      break;
141
142
1.46k
    case GEN_EDIPARTY:
143
6
      if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret)) {
144
0
        return nullptr;
145
0
      }
146
6
      break;
147
148
1.30k
    case GEN_EMAIL:
149
1.30k
      if (!x509V3_add_value_asn1_string("email", gen->d.ia5, &ret)) {
150
36
        return nullptr;
151
36
      }
152
1.27k
      break;
153
154
1.27k
    case GEN_DNS:
155
1.12k
      if (!x509V3_add_value_asn1_string("DNS", gen->d.ia5, &ret)) {
156
46
        return nullptr;
157
46
      }
158
1.07k
      break;
159
160
1.82k
    case GEN_URI:
161
1.82k
      if (!x509V3_add_value_asn1_string("URI", gen->d.ia5, &ret)) {
162
66
        return nullptr;
163
66
      }
164
1.75k
      break;
165
166
1.75k
    case GEN_DIRNAME:
167
354
      if (X509_NAME_oneline(gen->d.dirn, oline, 256) == nullptr ||
168
354
          !X509V3_add_value("DirName", oline, &ret)) {
169
0
        return nullptr;
170
0
      }
171
354
      break;
172
173
1.74k
    case GEN_IPADD:
174
1.74k
      p = gen->d.ip->data;
175
1.74k
      if (gen->d.ip->length == 4) {
176
555
        snprintf(oline, sizeof(oline), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
177
1.18k
      } else if (gen->d.ip->length == 16) {
178
249
        oline[0] = 0;
179
2.24k
        for (i = 0; i < 8; i++) {
180
1.99k
          uint16_t v = ((uint16_t)p[0] << 8) | p[1];
181
1.99k
          snprintf(htmp, sizeof(htmp), "%X", v);
182
1.99k
          p += 2;
183
1.99k
          OPENSSL_strlcat(oline, htmp, sizeof(oline));
184
1.99k
          if (i != 7) {
185
1.74k
            OPENSSL_strlcat(oline, ":", sizeof(oline));
186
1.74k
          }
187
1.99k
        }
188
936
      } else {
189
936
        if (!X509V3_add_value("IP Address", "<invalid>", &ret)) {
190
0
          return nullptr;
191
0
        }
192
936
        break;
193
936
      }
194
804
      if (!X509V3_add_value("IP Address", oline, &ret)) {
195
0
        return nullptr;
196
0
      }
197
804
      break;
198
199
1.94k
    case GEN_RID:
200
1.94k
      i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
201
1.94k
      if (!X509V3_add_value("Registered ID", oline, &ret)) {
202
0
        return nullptr;
203
0
      }
204
1.94k
      break;
205
9.91k
  }
206
9.76k
  return ret;
207
9.91k
}
208
209
2.07k
int GENERAL_NAME_print(BIO *out, const GENERAL_NAME *gen) {
210
2.07k
  switch (gen->type) {
211
58
    case GEN_OTHERNAME:
212
58
      BIO_printf(out, "othername:<unsupported>");
213
58
      break;
214
215
132
    case GEN_X400:
216
132
      BIO_printf(out, "X400Name:<unsupported>");
217
132
      break;
218
219
9
    case GEN_EDIPARTY:
220
      // Maybe fix this: it is supported now
221
9
      BIO_printf(out, "EdiPartyName:<unsupported>");
222
9
      break;
223
224
371
    case GEN_EMAIL:
225
371
      BIO_printf(out, "email:");
226
371
      ASN1_STRING_print(out, gen->d.ia5);
227
371
      break;
228
229
238
    case GEN_DNS:
230
238
      BIO_printf(out, "DNS:");
231
238
      ASN1_STRING_print(out, gen->d.ia5);
232
238
      break;
233
234
577
    case GEN_URI:
235
577
      BIO_printf(out, "URI:");
236
577
      ASN1_STRING_print(out, gen->d.ia5);
237
577
      break;
238
239
121
    case GEN_DIRNAME:
240
121
      BIO_printf(out, "DirName: ");
241
121
      X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
242
121
      break;
243
244
447
    case GEN_IPADD: {
245
447
      const unsigned char *p = gen->d.ip->data;
246
447
      if (gen->d.ip->length == 4) {
247
124
        BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
248
323
      } else if (gen->d.ip->length == 16) {
249
30
        BIO_printf(out, "IP Address");
250
270
        for (int i = 0; i < 8; i++) {
251
240
          uint16_t v = ((uint16_t)p[0] << 8) | p[1];
252
240
          BIO_printf(out, ":%X", v);
253
240
          p += 2;
254
240
        }
255
30
        BIO_puts(out, "\n");
256
293
      } else {
257
293
        BIO_printf(out, "IP Address:<invalid>");
258
293
        break;
259
293
      }
260
154
      break;
261
447
    }
262
263
154
    case GEN_RID:
264
120
      BIO_printf(out, "Registered ID");
265
120
      i2a_ASN1_OBJECT(out, gen->d.rid);
266
120
      break;
267
2.07k
  }
268
2.07k
  return 1;
269
2.07k
}
270
271
static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method,
272
                            const X509V3_CTX *ctx,
273
982
                            const STACK_OF(CONF_VALUE) *nval) {
274
982
  GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
275
982
  if (gens == nullptr) {
276
0
    return nullptr;
277
0
  }
278
4.63k
  for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
279
4.47k
    const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
280
4.47k
    if (x509v3_conf_name_matches(cnf->name, "issuer") && cnf->value &&
281
3.30k
        !strcmp(cnf->value, "copy")) {
282
3.29k
      if (!copy_issuer(ctx, gens)) {
283
695
        goto err;
284
695
      }
285
3.29k
    } else {
286
1.18k
      GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
287
1.18k
      if (gen == nullptr || !sk_GENERAL_NAME_push(gens, gen)) {
288
132
        GENERAL_NAME_free(gen);
289
132
        goto err;
290
132
      }
291
1.18k
    }
292
4.47k
  }
293
155
  return gens;
294
827
err:
295
827
  sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
296
827
  return nullptr;
297
982
}
298
299
// Append subject altname of issuer to issuer alt name of subject
300
301
3.29k
static int copy_issuer(const X509V3_CTX *ctx, GENERAL_NAMES *gens) {
302
3.29k
  if (ctx && (ctx->flags == X509V3_CTX_TEST)) {
303
0
    return 1;
304
0
  }
305
3.29k
  if (!ctx || !ctx->issuer_cert) {
306
441
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS);
307
441
    return 0;
308
441
  }
309
2.85k
  int i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
310
2.85k
  if (i < 0) {
311
594
    return 1;
312
594
  }
313
314
2.25k
  int ret = 0;
315
2.25k
  GENERAL_NAMES *ialt = nullptr;
316
2.25k
  X509_EXTENSION *ext;
317
2.25k
  if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
318
2.25k
      !(ialt = reinterpret_cast<GENERAL_NAMES *>(X509V3_EXT_d2i(ext)))) {
319
254
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR);
320
254
    goto err;
321
254
  }
322
323
169k
  for (size_t j = 0; j < sk_GENERAL_NAME_num(ialt); j++) {
324
167k
    GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, j);
325
167k
    if (!sk_GENERAL_NAME_push(gens, gen)) {
326
0
      goto err;
327
0
    }
328
    // Ownership of |gen| has moved from |ialt| to |gens|.
329
167k
    sk_GENERAL_NAME_set(ialt, j, nullptr);
330
167k
  }
331
332
2.00k
  ret = 1;
333
334
2.25k
err:
335
2.25k
  GENERAL_NAMES_free(ialt);
336
2.25k
  return ret;
337
2.00k
}
338
339
static void *v2i_subject_alt(const X509V3_EXT_METHOD *method,
340
                             const X509V3_CTX *ctx,
341
422
                             const STACK_OF(CONF_VALUE) *nval) {
342
422
  GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
343
422
  if (gens == nullptr) {
344
0
    return nullptr;
345
0
  }
346
10.3k
  for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
347
10.0k
    const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
348
10.0k
    if (x509v3_conf_name_matches(cnf->name, "email") && cnf->value &&
349
1.49k
        !strcmp(cnf->value, "copy")) {
350
261
      if (!copy_email(ctx, gens, 0)) {
351
20
        goto err;
352
20
      }
353
9.74k
    } else if (x509v3_conf_name_matches(cnf->name, "email") && cnf->value &&
354
1.23k
               !strcmp(cnf->value, "move")) {
355
234
      if (!copy_email(ctx, gens, 1)) {
356
17
        goto err;
357
17
      }
358
9.51k
    } else {
359
9.51k
      GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
360
9.51k
      if (gen == nullptr || !sk_GENERAL_NAME_push(gens, gen)) {
361
60
        GENERAL_NAME_free(gen);
362
60
        goto err;
363
60
      }
364
9.51k
    }
365
10.0k
  }
366
325
  return gens;
367
97
err:
368
97
  sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
369
97
  return nullptr;
370
422
}
371
372
// Copy any email addresses in a certificate or request to GENERAL_NAMES
373
374
495
static int copy_email(const X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) {
375
495
  X509_NAME *nm;
376
495
  ASN1_IA5STRING *email = nullptr;
377
495
  X509_NAME_ENTRY *ne;
378
495
  GENERAL_NAME *gen = nullptr;
379
495
  int i;
380
495
  if (ctx != nullptr && ctx->flags == X509V3_CTX_TEST) {
381
0
    return 1;
382
0
  }
383
495
  if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
384
37
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
385
37
    goto err;
386
37
  }
387
  // Find the subject name
388
458
  if (ctx->subject_cert) {
389
458
    nm = X509_get_subject_name(ctx->subject_cert);
390
458
  } else {
391
0
    nm = X509_REQ_get_subject_name(ctx->subject_req);
392
0
  }
393
394
  // Now add any email address(es) to STACK
395
458
  i = -1;
396
458
  while ((i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i)) >= 0) {
397
0
    ne = X509_NAME_get_entry(nm, i);
398
0
    email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
399
0
    if (move_p) {
400
0
      X509_NAME_delete_entry(nm, i);
401
0
      X509_NAME_ENTRY_free(ne);
402
0
      i--;
403
0
    }
404
0
    if (!email || !(gen = GENERAL_NAME_new())) {
405
0
      goto err;
406
0
    }
407
0
    gen->d.ia5 = email;
408
0
    email = nullptr;
409
0
    gen->type = GEN_EMAIL;
410
0
    if (!sk_GENERAL_NAME_push(gens, gen)) {
411
0
      goto err;
412
0
    }
413
0
    gen = nullptr;
414
0
  }
415
416
458
  return 1;
417
418
37
err:
419
37
  GENERAL_NAME_free(gen);
420
37
  ASN1_IA5STRING_free(email);
421
37
  return 0;
422
458
}
423
424
GENERAL_NAMES *bssl::v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
425
                                       const X509V3_CTX *ctx,
426
45.1k
                                       const STACK_OF(CONF_VALUE) *nval) {
427
45.1k
  GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
428
45.1k
  if (gens == nullptr) {
429
0
    return nullptr;
430
0
  }
431
97.7k
  for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
432
52.6k
    const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
433
52.6k
    GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
434
52.6k
    if (gen == nullptr || !sk_GENERAL_NAME_push(gens, gen)) {
435
16
      GENERAL_NAME_free(gen);
436
16
      goto err;
437
16
    }
438
52.6k
  }
439
45.0k
  return gens;
440
16
err:
441
16
  sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
442
16
  return nullptr;
443
45.1k
}
444
445
GENERAL_NAME *bssl::v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
446
                                     const X509V3_CTX *ctx,
447
65.9k
                                     const CONF_VALUE *cnf) {
448
65.9k
  return v2i_GENERAL_NAME_ex(nullptr, method, ctx, cnf, 0);
449
65.9k
}
450
451
static GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
452
                                      const X509V3_EXT_METHOD *method,
453
                                      const X509V3_CTX *ctx, int gen_type,
454
67.2k
                                      const char *value, int is_nc) {
455
67.2k
  if (!value) {
456
0
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
457
0
    return nullptr;
458
0
  }
459
460
67.2k
  GENERAL_NAME *gen = nullptr;
461
67.2k
  if (out) {
462
1.63k
    gen = out;
463
65.6k
  } else {
464
65.6k
    gen = GENERAL_NAME_new();
465
65.6k
    if (gen == nullptr) {
466
0
      return nullptr;
467
0
    }
468
65.6k
  }
469
470
67.2k
  switch (gen_type) {
471
9.19k
    case GEN_URI:
472
10.9k
    case GEN_EMAIL:
473
11.9k
    case GEN_DNS: {
474
11.9k
      ASN1_IA5STRING *str = ASN1_IA5STRING_new();
475
11.9k
      if (str == nullptr || !ASN1_STRING_set(str, value, strlen(value))) {
476
0
        ASN1_STRING_free(str);
477
0
        goto err;
478
0
      }
479
11.9k
      gen->type = gen_type;
480
11.9k
      gen->d.ia5 = str;
481
11.9k
      break;
482
11.9k
    }
483
484
535
    case GEN_RID: {
485
535
      ASN1_OBJECT *obj;
486
535
      if (!(obj = OBJ_txt2obj(value, 0))) {
487
4
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
488
4
        ERR_add_error_data(2, "value=", value);
489
4
        goto err;
490
4
      }
491
531
      gen->type = GEN_RID;
492
531
      gen->d.rid = obj;
493
531
      break;
494
535
    }
495
496
7.46k
    case GEN_IPADD:
497
7.46k
      gen->type = GEN_IPADD;
498
7.46k
      if (is_nc) {
499
496
        gen->d.ip = a2i_IPADDRESS_NC(value);
500
6.96k
      } else {
501
6.96k
        gen->d.ip = a2i_IPADDRESS(value);
502
6.96k
      }
503
7.46k
      if (gen->d.ip == nullptr) {
504
312
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
505
312
        ERR_add_error_data(2, "value=", value);
506
312
        goto err;
507
312
      }
508
7.14k
      break;
509
510
7.14k
    case GEN_DIRNAME:
511
6.20k
      if (!do_dirname(gen, value, ctx)) {
512
283
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
513
283
        goto err;
514
283
      }
515
5.91k
      break;
516
517
41.0k
    case GEN_OTHERNAME:
518
41.0k
      if (!do_othername(gen, value, ctx)) {
519
27
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
520
27
        goto err;
521
27
      }
522
41.0k
      break;
523
41.0k
    default:
524
0
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
525
0
      goto err;
526
67.2k
  }
527
528
66.6k
  return gen;
529
530
626
err:
531
626
  if (!out) {
532
596
    GENERAL_NAME_free(gen);
533
596
  }
534
626
  return nullptr;
535
67.2k
}
536
537
GENERAL_NAME *bssl::v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
538
                                        const X509V3_EXT_METHOD *method,
539
                                        const X509V3_CTX *ctx,
540
67.6k
                                        const CONF_VALUE *cnf, int is_nc) {
541
67.6k
  const char *name = cnf->name;
542
67.6k
  const char *value = cnf->value;
543
67.6k
  if (!value) {
544
169
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
545
169
    return nullptr;
546
169
  }
547
548
67.4k
  int type;
549
67.4k
  if (x509v3_conf_name_matches(name, "email")) {
550
1.70k
    type = GEN_EMAIL;
551
65.7k
  } else if (x509v3_conf_name_matches(name, "URI")) {
552
9.19k
    type = GEN_URI;
553
56.5k
  } else if (x509v3_conf_name_matches(name, "DNS")) {
554
1.06k
    type = GEN_DNS;
555
55.4k
  } else if (x509v3_conf_name_matches(name, "RID")) {
556
535
    type = GEN_RID;
557
54.9k
  } else if (x509v3_conf_name_matches(name, "IP")) {
558
7.46k
    type = GEN_IPADD;
559
47.4k
  } else if (x509v3_conf_name_matches(name, "dirName")) {
560
6.20k
    type = GEN_DIRNAME;
561
41.2k
  } else if (x509v3_conf_name_matches(name, "otherName")) {
562
41.0k
    type = GEN_OTHERNAME;
563
41.0k
  } else {
564
183
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
565
183
    ERR_add_error_data(2, "name=", name);
566
183
    return nullptr;
567
183
  }
568
569
67.2k
  return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
570
67.4k
}
571
572
static int do_othername(GENERAL_NAME *gen, const char *value,
573
41.0k
                        const X509V3_CTX *ctx) {
574
41.0k
  const char *semicolon = strchr(value, ';');
575
41.0k
  if (semicolon == nullptr) {
576
3
    return 0;
577
3
  }
578
579
41.0k
  OTHERNAME *name = OTHERNAME_new();
580
41.0k
  if (name == nullptr) {
581
0
    return 0;
582
0
  }
583
584
41.0k
  char *objtmp = OPENSSL_strndup(value, semicolon - value);
585
41.0k
  if (objtmp == nullptr) {
586
0
    goto err;
587
0
  }
588
41.0k
  ASN1_OBJECT_free(name->type_id);
589
41.0k
  name->type_id = OBJ_txt2obj(objtmp, /*dont_search_names=*/0);
590
41.0k
  OPENSSL_free(objtmp);
591
41.0k
  if (name->type_id == nullptr) {
592
9
    goto err;
593
9
  }
594
595
41.0k
  ASN1_TYPE_free(name->value);
596
41.0k
  name->value = ASN1_generate_v3(semicolon + 1, ctx);
597
41.0k
  if (name->value == nullptr) {
598
15
    goto err;
599
15
  }
600
601
41.0k
  gen->type = GEN_OTHERNAME;
602
41.0k
  gen->d.otherName = name;
603
41.0k
  return 1;
604
605
24
err:
606
24
  OTHERNAME_free(name);
607
24
  return 0;
608
41.0k
}
609
610
static int do_dirname(GENERAL_NAME *gen, const char *value,
611
6.20k
                      const X509V3_CTX *ctx) {
612
6.20k
  int ret = 0;
613
6.20k
  const STACK_OF(CONF_VALUE) *sk = X509V3_get_section(ctx, value);
614
6.20k
  X509_NAME *nm = X509_NAME_new();
615
6.20k
  if (nm == nullptr) {
616
0
    goto err;
617
0
  }
618
6.20k
  if (sk == nullptr) {
619
228
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
620
228
    ERR_add_error_data(2, "section=", value);
621
228
    goto err;
622
228
  }
623
  // FIXME: should allow other character types...
624
5.97k
  if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC)) {
625
55
    goto err;
626
55
  }
627
5.91k
  gen->type = GEN_DIRNAME;
628
5.91k
  gen->d.dirn = nm;
629
5.91k
  ret = 1;
630
631
6.20k
err:
632
6.20k
  if (!ret) {
633
283
    X509_NAME_free(nm);
634
283
  }
635
6.20k
  return ret;
636
5.91k
}