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