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