Coverage Report

Created: 2023-06-07 07:13

/src/boringssl/crypto/x509v3/v3_alt.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com). */
56
57
#include <stdio.h>
58
#include <string.h>
59
60
#include <openssl/conf.h>
61
#include <openssl/err.h>
62
#include <openssl/mem.h>
63
#include <openssl/obj.h>
64
#include <openssl/x509v3.h>
65
66
#include "../x509/internal.h"
67
#include "internal.h"
68
69
70
static void *v2i_subject_alt(const X509V3_EXT_METHOD *method,
71
                             const X509V3_CTX *ctx,
72
                             const STACK_OF(CONF_VALUE) *nval);
73
static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method,
74
                            const X509V3_CTX *ctx,
75
                            const STACK_OF(CONF_VALUE) *nval);
76
static int copy_email(const X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
77
static int copy_issuer(const X509V3_CTX *ctx, GENERAL_NAMES *gens);
78
static int do_othername(GENERAL_NAME *gen, const char *value,
79
                        const X509V3_CTX *ctx);
80
static int do_dirname(GENERAL_NAME *gen, const char *value,
81
                      const X509V3_CTX *ctx);
82
83
static STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES_cb(
84
348
    const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) {
85
348
  return i2v_GENERAL_NAMES(method, ext, ret);
86
348
}
87
88
const X509V3_EXT_METHOD v3_alt[] = {
89
    {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, 0, 0,
90
     i2v_GENERAL_NAMES_cb, v2i_subject_alt, NULL, NULL, NULL},
91
92
    {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, 0, 0,
93
     i2v_GENERAL_NAMES_cb, v2i_issuer_alt, NULL, NULL, NULL},
94
95
    {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, 0, 0,
96
     i2v_GENERAL_NAMES_cb, NULL, NULL, NULL, NULL},
97
};
98
99
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
100
                                        const GENERAL_NAMES *gens,
101
530
                                        STACK_OF(CONF_VALUE) *ret) {
102
530
  int ret_was_null = ret == NULL;
103
10.4k
  for (size_t i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
104
10.0k
    const GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
105
10.0k
    STACK_OF(CONF_VALUE) *tmp = i2v_GENERAL_NAME(method, gen, ret);
106
10.0k
    if (tmp == NULL) {
107
131
      if (ret_was_null) {
108
110
        sk_CONF_VALUE_pop_free(ret, X509V3_conf_free);
109
110
      }
110
131
      return NULL;
111
131
    }
112
9.93k
    ret = tmp;
113
9.93k
  }
114
399
  if (!ret) {
115
127
    return sk_CONF_VALUE_new_null();
116
127
  }
117
272
  return ret;
118
399
}
119
120
STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(const X509V3_EXT_METHOD *method,
121
                                       const GENERAL_NAME *gen,
122
10.1k
                                       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
10.1k
  unsigned char *p;
127
10.1k
  char oline[256], htmp[5];
128
10.1k
  int i;
129
10.1k
  switch (gen->type) {
130
119
    case GEN_OTHERNAME:
131
119
      if (!X509V3_add_value("othername", "<unsupported>", &ret)) {
132
0
        return NULL;
133
0
      }
134
119
      break;
135
136
1.88k
    case GEN_X400:
137
1.88k
      if (!X509V3_add_value("X400Name", "<unsupported>", &ret)) {
138
0
        return NULL;
139
0
      }
140
1.88k
      break;
141
142
1.88k
    case GEN_EDIPARTY:
143
3
      if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret)) {
144
0
        return NULL;
145
0
      }
146
3
      break;
147
148
1.13k
    case GEN_EMAIL:
149
1.13k
      if (!x509V3_add_value_asn1_string("email", gen->d.ia5, &ret)) {
150
39
        return NULL;
151
39
      }
152
1.09k
      break;
153
154
1.12k
    case GEN_DNS:
155
1.12k
      if (!x509V3_add_value_asn1_string("DNS", gen->d.ia5, &ret)) {
156
55
        return NULL;
157
55
      }
158
1.06k
      break;
159
160
1.06k
    case GEN_URI:
161
587
      if (!x509V3_add_value_asn1_string("URI", gen->d.ia5, &ret)) {
162
58
        return NULL;
163
58
      }
164
529
      break;
165
166
529
    case GEN_DIRNAME:
167
116
      if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL ||
168
116
          !X509V3_add_value("DirName", oline, &ret)) {
169
0
        return NULL;
170
0
      }
171
116
      break;
172
173
1.63k
    case GEN_IPADD:
174
1.63k
      p = gen->d.ip->data;
175
1.63k
      if (gen->d.ip->length == 4) {
176
1.05k
        BIO_snprintf(oline, sizeof(oline), "%d.%d.%d.%d", p[0], p[1], p[2],
177
1.05k
                     p[3]);
178
1.05k
      } else if (gen->d.ip->length == 16) {
179
355
        oline[0] = 0;
180
3.19k
        for (i = 0; i < 8; i++) {
181
2.84k
          uint16_t v = ((uint16_t)p[0] << 8) | p[1];
182
2.84k
          BIO_snprintf(htmp, sizeof(htmp), "%X", v);
183
2.84k
          p += 2;
184
2.84k
          OPENSSL_strlcat(oline, htmp, sizeof(oline));
185
2.84k
          if (i != 7) {
186
2.48k
            OPENSSL_strlcat(oline, ":", sizeof(oline));
187
2.48k
          }
188
2.84k
        }
189
355
      } else {
190
218
        if (!X509V3_add_value("IP Address", "<invalid>", &ret)) {
191
0
          return NULL;
192
0
        }
193
218
        break;
194
218
      }
195
1.41k
      if (!X509V3_add_value("IP Address", oline, &ret)) {
196
0
        return NULL;
197
0
      }
198
1.41k
      break;
199
200
3.57k
    case GEN_RID:
201
3.57k
      i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
202
3.57k
      if (!X509V3_add_value("Registered ID", oline, &ret)) {
203
0
        return NULL;
204
0
      }
205
3.57k
      break;
206
10.1k
  }
207
10.0k
  return ret;
208
10.1k
}
209
210
1.22k
int GENERAL_NAME_print(BIO *out, const GENERAL_NAME *gen) {
211
1.22k
  switch (gen->type) {
212
40
    case GEN_OTHERNAME:
213
40
      BIO_printf(out, "othername:<unsupported>");
214
40
      break;
215
216
189
    case GEN_X400:
217
189
      BIO_printf(out, "X400Name:<unsupported>");
218
189
      break;
219
220
0
    case GEN_EDIPARTY:
221
      // Maybe fix this: it is supported now
222
0
      BIO_printf(out, "EdiPartyName:<unsupported>");
223
0
      break;
224
225
118
    case GEN_EMAIL:
226
118
      BIO_printf(out, "email:");
227
118
      ASN1_STRING_print(out, gen->d.ia5);
228
118
      break;
229
230
115
    case GEN_DNS:
231
115
      BIO_printf(out, "DNS:");
232
115
      ASN1_STRING_print(out, gen->d.ia5);
233
115
      break;
234
235
156
    case GEN_URI:
236
156
      BIO_printf(out, "URI:");
237
156
      ASN1_STRING_print(out, gen->d.ia5);
238
156
      break;
239
240
257
    case GEN_DIRNAME:
241
257
      BIO_printf(out, "DirName: ");
242
257
      X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
243
257
      break;
244
245
207
    case GEN_IPADD: {
246
207
      const unsigned char *p = gen->d.ip->data;
247
207
      if (gen->d.ip->length == 4) {
248
103
        BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
249
104
      } else if (gen->d.ip->length == 16) {
250
42
        BIO_printf(out, "IP Address");
251
378
        for (int i = 0; i < 8; i++) {
252
336
          uint16_t v = ((uint16_t)p[0] << 8) | p[1];
253
336
          BIO_printf(out, ":%X", v);
254
336
          p += 2;
255
336
        }
256
42
        BIO_puts(out, "\n");
257
62
      } else {
258
62
        BIO_printf(out, "IP Address:<invalid>");
259
62
        break;
260
62
      }
261
145
      break;
262
207
    }
263
264
145
    case GEN_RID:
265
142
      BIO_printf(out, "Registered ID");
266
142
      i2a_ASN1_OBJECT(out, gen->d.rid);
267
142
      break;
268
1.22k
  }
269
1.22k
  return 1;
270
1.22k
}
271
272
static void *v2i_issuer_alt(const X509V3_EXT_METHOD *method,
273
                            const X509V3_CTX *ctx,
274
441
                            const STACK_OF(CONF_VALUE) *nval) {
275
441
  GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
276
441
  if (gens == NULL) {
277
0
    return NULL;
278
0
  }
279
2.53k
  for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
280
2.47k
    const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
281
2.47k
    if (x509v3_conf_name_matches(cnf->name, "issuer") && cnf->value &&
282
2.47k
        !strcmp(cnf->value, "copy")) {
283
1.57k
      if (!copy_issuer(ctx, gens)) {
284
277
        goto err;
285
277
      }
286
1.57k
    } else {
287
899
      GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
288
899
      if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) {
289
98
        GENERAL_NAME_free(gen);
290
98
        goto err;
291
98
      }
292
899
    }
293
2.47k
  }
294
66
  return gens;
295
375
err:
296
375
  sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
297
375
  return NULL;
298
441
}
299
300
// Append subject altname of issuer to issuer alt name of subject
301
302
1.57k
static int copy_issuer(const X509V3_CTX *ctx, GENERAL_NAMES *gens) {
303
1.57k
  if (ctx && (ctx->flags == X509V3_CTX_TEST)) {
304
0
    return 1;
305
0
  }
306
1.57k
  if (!ctx || !ctx->issuer_cert) {
307
186
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS);
308
186
    return 0;
309
186
  }
310
1.38k
  int i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
311
1.38k
  if (i < 0) {
312
488
    return 1;
313
488
  }
314
315
899
  int ret = 0;
316
899
  GENERAL_NAMES *ialt = NULL;
317
899
  X509_EXTENSION *ext;
318
899
  if (!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
319
899
      !(ialt = X509V3_EXT_d2i(ext))) {
320
91
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR);
321
91
    goto err;
322
91
  }
323
324
24.3k
  for (size_t j = 0; j < sk_GENERAL_NAME_num(ialt); j++) {
325
23.4k
    GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, j);
326
23.4k
    if (!sk_GENERAL_NAME_push(gens, gen)) {
327
0
      goto err;
328
0
    }
329
    // Ownership of |gen| has moved from |ialt| to |gens|.
330
23.4k
    sk_GENERAL_NAME_set(ialt, j, NULL);
331
23.4k
  }
332
333
808
  ret = 1;
334
335
899
err:
336
899
  GENERAL_NAMES_free(ialt);
337
899
  return ret;
338
808
}
339
340
static void *v2i_subject_alt(const X509V3_EXT_METHOD *method,
341
                             const X509V3_CTX *ctx,
342
262
                             const STACK_OF(CONF_VALUE) *nval) {
343
262
  GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
344
262
  if (gens == NULL) {
345
0
    return NULL;
346
0
  }
347
5.88k
  for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
348
5.70k
    const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
349
5.70k
    if (x509v3_conf_name_matches(cnf->name, "email") && cnf->value &&
350
5.70k
        !strcmp(cnf->value, "copy")) {
351
327
      if (!copy_email(ctx, gens, 0)) {
352
17
        goto err;
353
17
      }
354
5.37k
    } else if (x509v3_conf_name_matches(cnf->name, "email") && cnf->value &&
355
5.37k
               !strcmp(cnf->value, "move")) {
356
227
      if (!copy_email(ctx, gens, 1)) {
357
13
        goto err;
358
13
      }
359
5.15k
    } else {
360
5.15k
      GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
361
5.15k
      if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) {
362
56
        GENERAL_NAME_free(gen);
363
56
        goto err;
364
56
      }
365
5.15k
    }
366
5.70k
  }
367
176
  return gens;
368
86
err:
369
86
  sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
370
86
  return NULL;
371
262
}
372
373
// Copy any email addresses in a certificate or request to GENERAL_NAMES
374
375
554
static int copy_email(const X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) {
376
554
  X509_NAME *nm;
377
554
  ASN1_IA5STRING *email = NULL;
378
554
  X509_NAME_ENTRY *ne;
379
554
  GENERAL_NAME *gen = NULL;
380
554
  int i;
381
554
  if (ctx != NULL && ctx->flags == X509V3_CTX_TEST) {
382
0
    return 1;
383
0
  }
384
554
  if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
385
30
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
386
30
    goto err;
387
30
  }
388
  // Find the subject name
389
524
  if (ctx->subject_cert) {
390
524
    nm = X509_get_subject_name(ctx->subject_cert);
391
524
  } else {
392
0
    nm = X509_REQ_get_subject_name(ctx->subject_req);
393
0
  }
394
395
  // Now add any email address(es) to STACK
396
524
  i = -1;
397
524
  while ((i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i)) >= 0) {
398
0
    ne = X509_NAME_get_entry(nm, i);
399
0
    email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
400
0
    if (move_p) {
401
0
      X509_NAME_delete_entry(nm, i);
402
0
      X509_NAME_ENTRY_free(ne);
403
0
      i--;
404
0
    }
405
0
    if (!email || !(gen = GENERAL_NAME_new())) {
406
0
      goto err;
407
0
    }
408
0
    gen->d.ia5 = email;
409
0
    email = NULL;
410
0
    gen->type = GEN_EMAIL;
411
0
    if (!sk_GENERAL_NAME_push(gens, gen)) {
412
0
      goto err;
413
0
    }
414
0
    gen = NULL;
415
0
  }
416
417
524
  return 1;
418
419
30
err:
420
30
  GENERAL_NAME_free(gen);
421
30
  ASN1_IA5STRING_free(email);
422
30
  return 0;
423
524
}
424
425
GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
426
                                 const X509V3_CTX *ctx,
427
16.5k
                                 const STACK_OF(CONF_VALUE) *nval) {
428
16.5k
  GENERAL_NAMES *gens = sk_GENERAL_NAME_new_null();
429
16.5k
  if (gens == NULL) {
430
0
    return NULL;
431
0
  }
432
158k
  for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
433
142k
    const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
434
142k
    GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf);
435
142k
    if (gen == NULL || !sk_GENERAL_NAME_push(gens, gen)) {
436
43
      GENERAL_NAME_free(gen);
437
43
      goto err;
438
43
    }
439
142k
  }
440
16.4k
  return gens;
441
43
err:
442
43
  sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
443
43
  return NULL;
444
16.5k
}
445
446
GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
447
150k
                               const X509V3_CTX *ctx, const CONF_VALUE *cnf) {
448
150k
  return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
449
150k
}
450
451
GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
452
                               const X509V3_EXT_METHOD *method,
453
                               const X509V3_CTX *ctx, int gen_type,
454
152k
                               const char *value, int is_nc) {
455
152k
  if (!value) {
456
0
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
457
0
    return NULL;
458
0
  }
459
460
152k
  GENERAL_NAME *gen = NULL;
461
152k
  if (out) {
462
2.03k
    gen = out;
463
149k
  } else {
464
149k
    gen = GENERAL_NAME_new();
465
149k
    if (gen == NULL) {
466
0
      return NULL;
467
0
    }
468
149k
  }
469
470
152k
  switch (gen_type) {
471
7.71k
    case GEN_URI:
472
74.8k
    case GEN_EMAIL:
473
75.5k
    case GEN_DNS: {
474
75.5k
      ASN1_IA5STRING *str = ASN1_IA5STRING_new();
475
75.5k
      if (str == NULL || !ASN1_STRING_set(str, value, strlen(value))) {
476
0
        ASN1_STRING_free(str);
477
0
        goto err;
478
0
      }
479
75.5k
      gen->type = gen_type;
480
75.5k
      gen->d.ia5 = str;
481
75.5k
      break;
482
75.5k
    }
483
484
253
    case GEN_RID: {
485
253
      ASN1_OBJECT *obj;
486
253
      if (!(obj = OBJ_txt2obj(value, 0))) {
487
6
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
488
6
        ERR_add_error_data(2, "value=", value);
489
6
        goto err;
490
6
      }
491
247
      gen->type = GEN_RID;
492
247
      gen->d.rid = obj;
493
247
      break;
494
253
    }
495
496
4.36k
    case GEN_IPADD:
497
4.36k
      gen->type = GEN_IPADD;
498
4.36k
      if (is_nc) {
499
6
        gen->d.ip = a2i_IPADDRESS_NC(value);
500
4.36k
      } else {
501
4.36k
        gen->d.ip = a2i_IPADDRESS(value);
502
4.36k
      }
503
4.36k
      if (gen->d.ip == NULL) {
504
671
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
505
671
        ERR_add_error_data(2, "value=", value);
506
671
        goto err;
507
671
      }
508
3.69k
      break;
509
510
64.1k
    case GEN_DIRNAME:
511
64.1k
      if (!do_dirname(gen, value, ctx)) {
512
256
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
513
256
        goto err;
514
256
      }
515
63.8k
      break;
516
517
63.8k
    case GEN_OTHERNAME:
518
7.73k
      if (!do_othername(gen, value, ctx)) {
519
29
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
520
29
        goto err;
521
29
      }
522
7.70k
      break;
523
7.70k
    default:
524
0
      OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
525
0
      goto err;
526
152k
  }
527
528
151k
  return gen;
529
530
962
err:
531
962
  if (!out) {
532
950
    GENERAL_NAME_free(gen);
533
950
  }
534
962
  return NULL;
535
152k
}
536
537
GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
538
                                  const X509V3_EXT_METHOD *method,
539
                                  const X509V3_CTX *ctx, const CONF_VALUE *cnf,
540
152k
                                  int is_nc) {
541
152k
  const char *name = cnf->name;
542
152k
  const char *value = cnf->value;
543
152k
  if (!value) {
544
107
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
545
107
    return NULL;
546
107
  }
547
548
152k
  int type;
549
152k
  if (x509v3_conf_name_matches(name, "email")) {
550
67.1k
    type = GEN_EMAIL;
551
85.0k
  } else if (x509v3_conf_name_matches(name, "URI")) {
552
7.71k
    type = GEN_URI;
553
77.3k
  } else if (x509v3_conf_name_matches(name, "DNS")) {
554
676
    type = GEN_DNS;
555
76.6k
  } else if (x509v3_conf_name_matches(name, "RID")) {
556
253
    type = GEN_RID;
557
76.4k
  } else if (x509v3_conf_name_matches(name, "IP")) {
558
4.36k
    type = GEN_IPADD;
559
72.0k
  } else if (x509v3_conf_name_matches(name, "dirName")) {
560
64.1k
    type = GEN_DIRNAME;
561
64.1k
  } else if (x509v3_conf_name_matches(name, "otherName")) {
562
7.73k
    type = GEN_OTHERNAME;
563
7.73k
  } else {
564
179
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
565
179
    ERR_add_error_data(2, "name=", name);
566
179
    return NULL;
567
179
  }
568
569
152k
  return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
570
152k
}
571
572
static int do_othername(GENERAL_NAME *gen, const char *value,
573
7.73k
                        const X509V3_CTX *ctx) {
574
7.73k
  const char *semicolon = strchr(value, ';');
575
7.73k
  if (semicolon == NULL) {
576
3
    return 0;
577
3
  }
578
579
7.72k
  OTHERNAME *name = OTHERNAME_new();
580
7.72k
  if (name == NULL) {
581
0
    return 0;
582
0
  }
583
584
7.72k
  char *objtmp = OPENSSL_strndup(value, semicolon - value);
585
7.72k
  if (objtmp == NULL) {
586
0
    goto err;
587
0
  }
588
7.72k
  ASN1_OBJECT_free(name->type_id);
589
7.72k
  name->type_id = OBJ_txt2obj(objtmp, /*dont_search_names=*/0);
590
7.72k
  OPENSSL_free(objtmp);
591
7.72k
  if (name->type_id == NULL) {
592
11
    goto err;
593
11
  }
594
595
7.71k
  ASN1_TYPE_free(name->value);
596
7.71k
  name->value = ASN1_generate_v3(semicolon + 1, ctx);
597
7.71k
  if (name->value == NULL) {
598
15
    goto err;
599
15
  }
600
601
7.70k
  gen->type = GEN_OTHERNAME;
602
7.70k
  gen->d.otherName = name;
603
7.70k
  return 1;
604
605
26
err:
606
26
  OTHERNAME_free(name);
607
26
  return 0;
608
7.71k
}
609
610
static int do_dirname(GENERAL_NAME *gen, const char *value,
611
64.1k
                      const X509V3_CTX *ctx) {
612
64.1k
  int ret = 0;
613
64.1k
  X509_NAME *nm = X509_NAME_new();
614
64.1k
  if (nm == NULL) {
615
0
    goto err;
616
0
  }
617
64.1k
  const STACK_OF(CONF_VALUE) *sk = X509V3_get_section(ctx, value);
618
64.1k
  if (sk == NULL) {
619
224
    OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
620
224
    ERR_add_error_data(2, "section=", value);
621
224
    goto err;
622
224
  }
623
  // FIXME: should allow other character types...
624
63.9k
  if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC)) {
625
32
    goto err;
626
32
  }
627
63.8k
  gen->type = GEN_DIRNAME;
628
63.8k
  gen->d.dirn = nm;
629
63.8k
  ret = 1;
630
631
64.1k
err:
632
64.1k
  if (!ret) {
633
256
    X509_NAME_free(nm);
634
256
  }
635
64.1k
  return ret;
636
63.8k
}