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