]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - crypto/openssl/crypto/asn1/x_name.c
Fix multiple OpenSSL vulnerabilities.
[FreeBSD/releng/9.3.git] / crypto / openssl / crypto / asn1 / x_name.c
1 /* crypto/asn1/x_name.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #include <stdio.h>
60 #include "cryptlib.h"
61 #include <openssl/asn1t.h>
62 #include <openssl/x509.h>
63
64 static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
65                             long len, const ASN1_ITEM *it, int tag,
66                             int aclass, char opt, ASN1_TLC *ctx);
67
68 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
69                             const ASN1_ITEM *it, int tag, int aclass);
70 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
71 static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
72
73 static int x509_name_encode(X509_NAME *a);
74
75 ASN1_SEQUENCE(X509_NAME_ENTRY) = {
76         ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
77         ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
78 } ASN1_SEQUENCE_END(X509_NAME_ENTRY)
79
80 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
81 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
82
83 /*
84  * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
85  * declare two template wrappers for this
86  */
87
88 ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
89         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
90 ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
91
92 ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
93         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
94 ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
95
96 /*
97  * Normally that's where it would end: we'd have two nested STACK structures
98  * representing the ASN1. Unfortunately X509_NAME uses a completely different
99  * form and caches encodings so we have to process the internal form and
100  * convert to the external form.
101  */
102
103 const ASN1_EXTERN_FUNCS x509_name_ff = {
104     NULL,
105     x509_name_ex_new,
106     x509_name_ex_free,
107     0,                          /* Default clear behaviour is OK */
108     x509_name_ex_d2i,
109     x509_name_ex_i2d
110 };
111
112 IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
113
114 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
115
116 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
117
118 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
119 {
120     X509_NAME *ret = NULL;
121     ret = OPENSSL_malloc(sizeof(X509_NAME));
122     if (!ret)
123         goto memerr;
124     if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
125         goto memerr;
126     if ((ret->bytes = BUF_MEM_new()) == NULL)
127         goto memerr;
128     ret->modified = 1;
129     *val = (ASN1_VALUE *)ret;
130     return 1;
131
132  memerr:
133     ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
134     if (ret) {
135         if (ret->entries)
136             sk_X509_NAME_ENTRY_free(ret->entries);
137         OPENSSL_free(ret);
138     }
139     return 0;
140 }
141
142 static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
143 {
144     X509_NAME *a;
145     if (!pval || !*pval)
146         return;
147     a = (X509_NAME *)*pval;
148
149     BUF_MEM_free(a->bytes);
150     sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
151     OPENSSL_free(a);
152     *pval = NULL;
153 }
154
155 /*
156  * Used with sk_pop_free() to free up the internal representation. NB: we
157  * only free the STACK and not its contents because it is already present in
158  * the X509_NAME structure.
159  */
160
161 static void sk_internal_free(void *a)
162 {
163     sk_free(a);
164 }
165
166 static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
167                             long len, const ASN1_ITEM *it, int tag,
168                             int aclass, char opt, ASN1_TLC *ctx)
169 {
170     const unsigned char *p = *in, *q;
171     union {
172         STACK *s;
173         ASN1_VALUE *a;
174     } intname = {
175         NULL
176     };
177     union {
178         X509_NAME *x;
179         ASN1_VALUE *a;
180     } nm = {
181         NULL
182     };
183     int i, j, ret;
184     STACK_OF(X509_NAME_ENTRY) *entries;
185     X509_NAME_ENTRY *entry;
186     q = p;
187
188     /* Get internal representation of Name */
189     ret = ASN1_item_ex_d2i(&intname.a,
190                            &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
191                            tag, aclass, opt, ctx);
192
193     if (ret <= 0)
194         return ret;
195
196     if (*val)
197         x509_name_ex_free(val, NULL);
198     if (!x509_name_ex_new(&nm.a, NULL))
199         goto err;
200     /* We've decoded it: now cache encoding */
201     if (!BUF_MEM_grow(nm.x->bytes, p - q))
202         goto err;
203     memcpy(nm.x->bytes->data, q, p - q);
204
205     /* Convert internal representation to X509_NAME structure */
206     for (i = 0; i < sk_num(intname.s); i++) {
207         entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i);
208         for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
209             entry = sk_X509_NAME_ENTRY_value(entries, j);
210             entry->set = i;
211             if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
212                 goto err;
213         }
214         sk_X509_NAME_ENTRY_free(entries);
215     }
216     sk_free(intname.s);
217     nm.x->modified = 0;
218     *val = nm.a;
219     *in = p;
220     return ret;
221  err:
222     if (nm.x != NULL)
223         X509_NAME_free(nm.x);
224     ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
225     return 0;
226 }
227
228 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
229                             const ASN1_ITEM *it, int tag, int aclass)
230 {
231     int ret;
232     X509_NAME *a = (X509_NAME *)*val;
233     if (a->modified) {
234         ret = x509_name_encode((X509_NAME *)a);
235         if (ret < 0)
236             return ret;
237     }
238     ret = a->bytes->length;
239     if (out != NULL) {
240         memcpy(*out, a->bytes->data, ret);
241         *out += ret;
242     }
243     return ret;
244 }
245
246 static int x509_name_encode(X509_NAME *a)
247 {
248     union {
249         STACK *s;
250         ASN1_VALUE *a;
251     } intname = {
252         NULL
253     };
254     int len;
255     unsigned char *p;
256     STACK_OF(X509_NAME_ENTRY) *entries = NULL;
257     X509_NAME_ENTRY *entry;
258     int i, set = -1;
259     intname.s = sk_new_null();
260     if (!intname.s)
261         goto memerr;
262     for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
263         entry = sk_X509_NAME_ENTRY_value(a->entries, i);
264         if (entry->set != set) {
265             entries = sk_X509_NAME_ENTRY_new_null();
266             if (!entries)
267                 goto memerr;
268             if (!sk_push(intname.s, (char *)entries))
269                 goto memerr;
270             set = entry->set;
271         }
272         if (!sk_X509_NAME_ENTRY_push(entries, entry))
273             goto memerr;
274     }
275     len = ASN1_item_ex_i2d(&intname.a, NULL,
276                            ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
277     if (!BUF_MEM_grow(a->bytes, len))
278         goto memerr;
279     p = (unsigned char *)a->bytes->data;
280     ASN1_item_ex_i2d(&intname.a,
281                      &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
282     sk_pop_free(intname.s, sk_internal_free);
283     a->modified = 0;
284     return len;
285  memerr:
286     sk_pop_free(intname.s, sk_internal_free);
287     ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
288     return -1;
289 }
290
291 int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
292 {
293     X509_NAME *in;
294
295     if (!xn || !name)
296         return (0);
297
298     if (*xn != name) {
299         in = X509_NAME_dup(name);
300         if (in != NULL) {
301             X509_NAME_free(*xn);
302             *xn = in;
303         }
304     }
305     return (*xn != NULL);
306 }
307
308 IMPLEMENT_STACK_OF(X509_NAME_ENTRY)
309
310 IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)