File: | src/lib/libcrypto/asn1/x_name.c |
Warning: | line 343, column 2 Potential leak of memory pointed to by 'nm.a' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: x_name.c,v 1.37 2021/12/25 13:17:48 jsing Exp $ */ | |||
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 <ctype.h> | |||
60 | #include <stdio.h> | |||
61 | #include <string.h> | |||
62 | ||||
63 | #include <openssl/asn1t.h> | |||
64 | #include <openssl/err.h> | |||
65 | #include <openssl/x509.h> | |||
66 | ||||
67 | #include "asn1_locl.h" | |||
68 | #include "x509_lcl.h" | |||
69 | ||||
70 | typedef STACK_OF(X509_NAME_ENTRY)struct stack_st_X509_NAME_ENTRY STACK_OF_X509_NAME_ENTRY; | |||
71 | DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)struct stack_st_STACK_OF_X509_NAME_ENTRY { _STACK stack; }; | |||
72 | ||||
73 | static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, | |||
74 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt, | |||
75 | ASN1_TLC *ctx); | |||
76 | ||||
77 | static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, | |||
78 | const ASN1_ITEM *it, int tag, int aclass); | |||
79 | static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); | |||
80 | static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); | |||
81 | ||||
82 | static int x509_name_encode(X509_NAME *a); | |||
83 | static int x509_name_canon(X509_NAME *a); | |||
84 | static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); | |||
85 | static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY)struct stack_st_STACK_OF_X509_NAME_ENTRY *intname, | |||
86 | unsigned char **in); | |||
87 | ||||
88 | static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent, | |||
89 | const char *fname, const ASN1_PCTX *pctx); | |||
90 | ||||
91 | static const ASN1_TEMPLATE X509_NAME_ENTRY_seq_tt[] = { | |||
92 | { | |||
93 | .offset = offsetof(X509_NAME_ENTRY, object)__builtin_offsetof(X509_NAME_ENTRY, object), | |||
94 | .field_name = "object", | |||
95 | .item = &ASN1_OBJECT_it, | |||
96 | }, | |||
97 | { | |||
98 | .offset = offsetof(X509_NAME_ENTRY, value)__builtin_offsetof(X509_NAME_ENTRY, value), | |||
99 | .field_name = "value", | |||
100 | .item = &ASN1_PRINTABLE_it, | |||
101 | }, | |||
102 | }; | |||
103 | ||||
104 | const ASN1_ITEM X509_NAME_ENTRY_it = { | |||
105 | .itype = ASN1_ITYPE_SEQUENCE0x1, | |||
106 | .utype = V_ASN1_SEQUENCE16, | |||
107 | .templates = X509_NAME_ENTRY_seq_tt, | |||
108 | .tcount = sizeof(X509_NAME_ENTRY_seq_tt) / sizeof(ASN1_TEMPLATE), | |||
109 | .size = sizeof(X509_NAME_ENTRY), | |||
110 | .sname = "X509_NAME_ENTRY", | |||
111 | }; | |||
112 | ||||
113 | ||||
114 | X509_NAME_ENTRY * | |||
115 | d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, const unsigned char **in, long len) | |||
116 | { | |||
117 | return (X509_NAME_ENTRY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, | |||
118 | &X509_NAME_ENTRY_it); | |||
119 | } | |||
120 | ||||
121 | int | |||
122 | i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **out) | |||
123 | { | |||
124 | return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_ENTRY_it); | |||
125 | } | |||
126 | ||||
127 | X509_NAME_ENTRY * | |||
128 | X509_NAME_ENTRY_new(void) | |||
129 | { | |||
130 | return (X509_NAME_ENTRY *)ASN1_item_new(&X509_NAME_ENTRY_it); | |||
131 | } | |||
132 | ||||
133 | void | |||
134 | X509_NAME_ENTRY_free(X509_NAME_ENTRY *a) | |||
135 | { | |||
136 | ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_ENTRY_it); | |||
137 | } | |||
138 | ||||
139 | X509_NAME_ENTRY * | |||
140 | X509_NAME_ENTRY_dup(X509_NAME_ENTRY *x) | |||
141 | { | |||
142 | return ASN1_item_dup(&X509_NAME_ENTRY_it, x); | |||
143 | } | |||
144 | ||||
145 | /* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } | |||
146 | * so declare two template wrappers for this | |||
147 | */ | |||
148 | ||||
149 | static const ASN1_TEMPLATE X509_NAME_ENTRIES_item_tt = { | |||
150 | .flags = ASN1_TFLG_SET_OF(0x1 << 1), | |||
151 | .tag = 0, | |||
152 | .offset = 0, | |||
153 | .field_name = "RDNS", | |||
154 | .item = &X509_NAME_ENTRY_it, | |||
155 | }; | |||
156 | ||||
157 | const ASN1_ITEM X509_NAME_ENTRIES_it = { | |||
158 | .itype = ASN1_ITYPE_PRIMITIVE0x0, | |||
159 | .utype = -1, | |||
160 | .templates = &X509_NAME_ENTRIES_item_tt, | |||
161 | .tcount = 0, | |||
162 | .funcs = NULL((void*)0), | |||
163 | .size = 0, | |||
164 | .sname = "X509_NAME_ENTRIES", | |||
165 | }; | |||
166 | ||||
167 | static const ASN1_TEMPLATE X509_NAME_INTERNAL_item_tt = { | |||
168 | .flags = ASN1_TFLG_SEQUENCE_OF(0x2 << 1), | |||
169 | .tag = 0, | |||
170 | .offset = 0, | |||
171 | .field_name = "Name", | |||
172 | .item = &X509_NAME_ENTRIES_it, | |||
173 | }; | |||
174 | ||||
175 | const ASN1_ITEM X509_NAME_INTERNAL_it = { | |||
176 | .itype = ASN1_ITYPE_PRIMITIVE0x0, | |||
177 | .utype = -1, | |||
178 | .templates = &X509_NAME_INTERNAL_item_tt, | |||
179 | .tcount = 0, | |||
180 | .funcs = NULL((void*)0), | |||
181 | .size = 0, | |||
182 | .sname = "X509_NAME_INTERNAL", | |||
183 | }; | |||
184 | ||||
185 | /* Normally that's where it would end: we'd have two nested STACK structures | |||
186 | * representing the ASN1. Unfortunately X509_NAME uses a completely different | |||
187 | * form and caches encodings so we have to process the internal form and convert | |||
188 | * to the external form. | |||
189 | */ | |||
190 | ||||
191 | const ASN1_EXTERN_FUNCS x509_name_ff = { | |||
192 | NULL((void*)0), | |||
193 | x509_name_ex_new, | |||
194 | x509_name_ex_free, | |||
195 | 0, /* Default clear behaviour is OK */ | |||
196 | x509_name_ex_d2i, | |||
197 | x509_name_ex_i2d, | |||
198 | x509_name_ex_print | |||
199 | }; | |||
200 | ||||
201 | const ASN1_ITEM X509_NAME_it = { | |||
202 | .itype = ASN1_ITYPE_EXTERN0x4, | |||
203 | .utype = V_ASN1_SEQUENCE16, | |||
204 | .templates = NULL((void*)0), | |||
205 | .tcount = 0, | |||
206 | .funcs = &x509_name_ff, | |||
207 | .size = 0, | |||
208 | .sname = "X509_NAME", | |||
209 | }; | |||
210 | ||||
211 | X509_NAME * | |||
212 | d2i_X509_NAME(X509_NAME **a, const unsigned char **in, long len) | |||
213 | { | |||
214 | return (X509_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, | |||
215 | &X509_NAME_it); | |||
216 | } | |||
217 | ||||
218 | int | |||
219 | i2d_X509_NAME(X509_NAME *a, unsigned char **out) | |||
220 | { | |||
221 | return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_it); | |||
222 | } | |||
223 | ||||
224 | X509_NAME * | |||
225 | X509_NAME_new(void) | |||
226 | { | |||
227 | return (X509_NAME *)ASN1_item_new(&X509_NAME_it); | |||
228 | } | |||
229 | ||||
230 | void | |||
231 | X509_NAME_free(X509_NAME *a) | |||
232 | { | |||
233 | ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_it); | |||
234 | } | |||
235 | ||||
236 | X509_NAME * | |||
237 | X509_NAME_dup(X509_NAME *x) | |||
238 | { | |||
239 | return ASN1_item_dup(&X509_NAME_it, x); | |||
240 | } | |||
241 | ||||
242 | static int | |||
243 | x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) | |||
244 | { | |||
245 | X509_NAME *ret = NULL((void*)0); | |||
246 | ||||
247 | ret = malloc(sizeof(X509_NAME)); | |||
248 | if (!ret) | |||
249 | goto memerr; | |||
250 | if ((ret->entries = sk_X509_NAME_ENTRY_new_null()((struct stack_st_X509_NAME_ENTRY *)sk_new_null())) == NULL((void*)0)) | |||
251 | goto memerr; | |||
252 | if ((ret->bytes = BUF_MEM_new()) == NULL((void*)0)) | |||
253 | goto memerr; | |||
254 | ret->canon_enc = NULL((void*)0); | |||
255 | ret->canon_enclen = 0; | |||
256 | ret->modified = 1; | |||
257 | *val = (ASN1_VALUE *)ret; | |||
258 | return 1; | |||
259 | ||||
260 | memerr: | |||
261 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/x_name.c" ,261); | |||
262 | if (ret) { | |||
263 | if (ret->entries) | |||
264 | sk_X509_NAME_ENTRY_free(ret->entries)sk_free(((_STACK*) (1 ? (ret->entries) : (struct stack_st_X509_NAME_ENTRY *)0))); | |||
265 | free(ret); | |||
266 | } | |||
267 | return 0; | |||
268 | } | |||
269 | ||||
270 | static void | |||
271 | x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | |||
272 | { | |||
273 | X509_NAME *a; | |||
274 | ||||
275 | if (!pval || !*pval) | |||
276 | return; | |||
277 | a = (X509_NAME *)*pval; | |||
278 | ||||
279 | BUF_MEM_free(a->bytes); | |||
280 | sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free)sk_pop_free(((_STACK*) (1 ? (a->entries) : (struct stack_st_X509_NAME_ENTRY *)0)), ((void (*)(void *)) ((1 ? (X509_NAME_ENTRY_free) : (void (*)(X509_NAME_ENTRY *))0)))); | |||
281 | free(a->canon_enc); | |||
282 | free(a); | |||
283 | *pval = NULL((void*)0); | |||
284 | } | |||
285 | ||||
286 | static int | |||
287 | x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, | |||
288 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx) | |||
289 | { | |||
290 | const unsigned char *p = *in, *q; | |||
291 | union { | |||
292 | STACK_OF(STACK_OF_X509_NAME_ENTRY)struct stack_st_STACK_OF_X509_NAME_ENTRY *s; | |||
293 | ASN1_VALUE *a; | |||
294 | } intname = {NULL((void*)0)}; | |||
295 | union { | |||
296 | X509_NAME *x; | |||
297 | ASN1_VALUE *a; | |||
298 | } nm = {NULL((void*)0)}; | |||
299 | int i, j, ret; | |||
300 | STACK_OF(X509_NAME_ENTRY)struct stack_st_X509_NAME_ENTRY *entries; | |||
301 | X509_NAME_ENTRY *entry; | |||
302 | q = p; | |||
303 | ||||
304 | /* Get internal representation of Name */ | |||
305 | ret = ASN1_item_ex_d2i(&intname.a, &p, len, | |||
306 | &X509_NAME_INTERNAL_it, tag, aclass, opt, ctx); | |||
307 | ||||
308 | if (ret <= 0) | |||
| ||||
309 | return ret; | |||
310 | ||||
311 | if (*val) | |||
312 | x509_name_ex_free(val, NULL((void*)0)); | |||
313 | if (!x509_name_ex_new(&nm.a, NULL((void*)0))) | |||
314 | goto err; | |||
315 | /* We've decoded it: now cache encoding */ | |||
316 | if (!BUF_MEM_grow(nm.x->bytes, p - q)) | |||
317 | goto err; | |||
318 | memcpy(nm.x->bytes->data, q, p - q); | |||
319 | ||||
320 | /* Convert internal representation to X509_NAME structure */ | |||
321 | for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s)sk_num(((_STACK*) (1 ? (intname.s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0))); i++) { | |||
322 | entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i)((STACK_OF_X509_NAME_ENTRY *)sk_value(((_STACK*) (1 ? (intname .s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY*)0)), (i))); | |||
323 | for (j = 0; j < sk_X509_NAME_ENTRY_num(entries)sk_num(((_STACK*) (1 ? (entries) : (struct stack_st_X509_NAME_ENTRY *)0))); j++) { | |||
324 | entry = sk_X509_NAME_ENTRY_value(entries, j)((X509_NAME_ENTRY *)sk_value(((_STACK*) (1 ? (entries) : (struct stack_st_X509_NAME_ENTRY*)0)), (j))); | |||
325 | entry->set = i; | |||
326 | if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)sk_push(((_STACK*) (1 ? (nm.x->entries) : (struct stack_st_X509_NAME_ENTRY *)0)), ((void*) (1 ? (entry) : (X509_NAME_ENTRY*)0)))) | |||
327 | goto err; | |||
328 | } | |||
329 | sk_X509_NAME_ENTRY_free(entries)sk_free(((_STACK*) (1 ? (entries) : (struct stack_st_X509_NAME_ENTRY *)0))); | |||
330 | } | |||
331 | sk_STACK_OF_X509_NAME_ENTRY_free(intname.s)sk_free(((_STACK*) (1 ? (intname.s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0))); | |||
332 | ret = x509_name_canon(nm.x); | |||
333 | if (!ret) | |||
334 | goto err; | |||
335 | nm.x->modified = 0; | |||
336 | *val = nm.a; | |||
337 | *in = p; | |||
338 | return ret; | |||
339 | ||||
340 | err: | |||
341 | if (nm.x != NULL((void*)0)) | |||
342 | X509_NAME_free(nm.x); | |||
343 | ASN1error(ERR_R_NESTED_ASN1_ERROR)ERR_put_error(13,(0xfff),(58),"/usr/src/lib/libcrypto/asn1/x_name.c" ,343); | |||
| ||||
344 | return 0; | |||
345 | } | |||
346 | ||||
347 | static int | |||
348 | x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, | |||
349 | int tag, int aclass) | |||
350 | { | |||
351 | int ret; | |||
352 | X509_NAME *a = (X509_NAME *)*val; | |||
353 | ||||
354 | if (a->modified) { | |||
355 | ret = x509_name_encode(a); | |||
356 | if (ret < 0) | |||
357 | return ret; | |||
358 | ret = x509_name_canon(a); | |||
359 | if (ret < 0) | |||
360 | return ret; | |||
361 | } | |||
362 | ret = a->bytes->length; | |||
363 | if (out != NULL((void*)0)) { | |||
364 | memcpy(*out, a->bytes->data, ret); | |||
365 | *out += ret; | |||
366 | } | |||
367 | return ret; | |||
368 | } | |||
369 | ||||
370 | static void | |||
371 | local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY)struct stack_st_X509_NAME_ENTRY *ne) | |||
372 | { | |||
373 | sk_X509_NAME_ENTRY_free(ne)sk_free(((_STACK*) (1 ? (ne) : (struct stack_st_X509_NAME_ENTRY *)0))); | |||
374 | } | |||
375 | ||||
376 | static void | |||
377 | local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY)struct stack_st_X509_NAME_ENTRY *ne) | |||
378 | { | |||
379 | sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free)sk_pop_free(((_STACK*) (1 ? (ne) : (struct stack_st_X509_NAME_ENTRY *)0)), ((void (*)(void *)) ((1 ? (X509_NAME_ENTRY_free) : (void (*)(X509_NAME_ENTRY *))0)))); | |||
380 | } | |||
381 | ||||
382 | static int | |||
383 | x509_name_encode(X509_NAME *a) | |||
384 | { | |||
385 | union { | |||
386 | STACK_OF(STACK_OF_X509_NAME_ENTRY)struct stack_st_STACK_OF_X509_NAME_ENTRY *s; | |||
387 | ASN1_VALUE *a; | |||
388 | } intname = {NULL((void*)0)}; | |||
389 | int len; | |||
390 | unsigned char *p; | |||
391 | STACK_OF(X509_NAME_ENTRY)struct stack_st_X509_NAME_ENTRY *entries = NULL((void*)0); | |||
392 | X509_NAME_ENTRY *entry; | |||
393 | int i, set = -1; | |||
394 | ||||
395 | intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null()((struct stack_st_STACK_OF_X509_NAME_ENTRY *)sk_new_null()); | |||
396 | if (!intname.s) | |||
397 | goto memerr; | |||
398 | for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries)sk_num(((_STACK*) (1 ? (a->entries) : (struct stack_st_X509_NAME_ENTRY *)0))); i++) { | |||
399 | entry = sk_X509_NAME_ENTRY_value(a->entries, i)((X509_NAME_ENTRY *)sk_value(((_STACK*) (1 ? (a->entries) : (struct stack_st_X509_NAME_ENTRY*)0)), (i))); | |||
400 | if (entry->set != set) { | |||
401 | entries = sk_X509_NAME_ENTRY_new_null()((struct stack_st_X509_NAME_ENTRY *)sk_new_null()); | |||
402 | if (!entries) | |||
403 | goto memerr; | |||
404 | if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,sk_push(((_STACK*) (1 ? (intname.s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void*) (1 ? (entries) : (STACK_OF_X509_NAME_ENTRY*)0 ))) | |||
405 | entries)sk_push(((_STACK*) (1 ? (intname.s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void*) (1 ? (entries) : (STACK_OF_X509_NAME_ENTRY*)0 )))) | |||
406 | goto memerr; | |||
407 | set = entry->set; | |||
408 | } | |||
409 | if (entries == NULL((void*)0) /* if entry->set is bogusly -1 */ || | |||
410 | !sk_X509_NAME_ENTRY_push(entries, entry)sk_push(((_STACK*) (1 ? (entries) : (struct stack_st_X509_NAME_ENTRY *)0)), ((void*) (1 ? (entry) : (X509_NAME_ENTRY*)0)))) | |||
411 | goto memerr; | |||
412 | } | |||
413 | len = ASN1_item_ex_i2d(&intname.a, NULL((void*)0), | |||
414 | &X509_NAME_INTERNAL_it, -1, -1); | |||
415 | if (!BUF_MEM_grow(a->bytes, len)) | |||
416 | goto memerr; | |||
417 | p = (unsigned char *)a->bytes->data; | |||
418 | ASN1_item_ex_i2d(&intname.a, &p, &X509_NAME_INTERNAL_it, | |||
419 | -1, -1); | |||
420 | sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,sk_pop_free(((_STACK*) (1 ? (intname.s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void (*)(void *)) ((1 ? (local_sk_X509_NAME_ENTRY_free ) : (void (*)(STACK_OF_X509_NAME_ENTRY *))0)))) | |||
421 | local_sk_X509_NAME_ENTRY_free)sk_pop_free(((_STACK*) (1 ? (intname.s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void (*)(void *)) ((1 ? (local_sk_X509_NAME_ENTRY_free ) : (void (*)(STACK_OF_X509_NAME_ENTRY *))0)))); | |||
422 | a->modified = 0; | |||
423 | return len; | |||
424 | ||||
425 | memerr: | |||
426 | sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,sk_pop_free(((_STACK*) (1 ? (intname.s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void (*)(void *)) ((1 ? (local_sk_X509_NAME_ENTRY_free ) : (void (*)(STACK_OF_X509_NAME_ENTRY *))0)))) | |||
427 | local_sk_X509_NAME_ENTRY_free)sk_pop_free(((_STACK*) (1 ? (intname.s) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void (*)(void *)) ((1 ? (local_sk_X509_NAME_ENTRY_free ) : (void (*)(STACK_OF_X509_NAME_ENTRY *))0)))); | |||
428 | ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/x_name.c" ,428); | |||
429 | return -1; | |||
430 | } | |||
431 | ||||
432 | static int | |||
433 | x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent, const char *fname, | |||
434 | const ASN1_PCTX *pctx) | |||
435 | { | |||
436 | if (X509_NAME_print_ex(out, (X509_NAME *)*pval, indent, | |||
437 | pctx->nm_flags) <= 0) | |||
438 | return 0; | |||
439 | return 2; | |||
440 | } | |||
441 | ||||
442 | /* This function generates the canonical encoding of the Name structure. | |||
443 | * In it all strings are converted to UTF8, leading, trailing and | |||
444 | * multiple spaces collapsed, converted to lower case and the leading | |||
445 | * SEQUENCE header removed. | |||
446 | * | |||
447 | * In future we could also normalize the UTF8 too. | |||
448 | * | |||
449 | * By doing this comparison of Name structures can be rapidly | |||
450 | * performed by just using memcmp() of the canonical encoding. | |||
451 | * By omitting the leading SEQUENCE name constraints of type | |||
452 | * dirName can also be checked with a simple memcmp(). | |||
453 | */ | |||
454 | ||||
455 | static int | |||
456 | x509_name_canon(X509_NAME *a) | |||
457 | { | |||
458 | unsigned char *p; | |||
459 | STACK_OF(STACK_OF_X509_NAME_ENTRY)struct stack_st_STACK_OF_X509_NAME_ENTRY *intname = NULL((void*)0); | |||
460 | STACK_OF(X509_NAME_ENTRY)struct stack_st_X509_NAME_ENTRY *entries = NULL((void*)0); | |||
461 | X509_NAME_ENTRY *entry, *tmpentry = NULL((void*)0); | |||
462 | int i, len, set = -1, ret = 0; | |||
463 | ||||
464 | if (a->canon_enc) { | |||
465 | free(a->canon_enc); | |||
466 | a->canon_enc = NULL((void*)0); | |||
467 | } | |||
468 | /* Special case: empty X509_NAME => null encoding */ | |||
469 | if (sk_X509_NAME_ENTRY_num(a->entries)sk_num(((_STACK*) (1 ? (a->entries) : (struct stack_st_X509_NAME_ENTRY *)0))) == 0) { | |||
470 | a->canon_enclen = 0; | |||
471 | return 1; | |||
472 | } | |||
473 | intname = sk_STACK_OF_X509_NAME_ENTRY_new_null()((struct stack_st_STACK_OF_X509_NAME_ENTRY *)sk_new_null()); | |||
474 | if (!intname) | |||
475 | goto err; | |||
476 | for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries)sk_num(((_STACK*) (1 ? (a->entries) : (struct stack_st_X509_NAME_ENTRY *)0))); i++) { | |||
477 | entry = sk_X509_NAME_ENTRY_value(a->entries, i)((X509_NAME_ENTRY *)sk_value(((_STACK*) (1 ? (a->entries) : (struct stack_st_X509_NAME_ENTRY*)0)), (i))); | |||
478 | if (entry->set != set) { | |||
479 | entries = sk_X509_NAME_ENTRY_new_null()((struct stack_st_X509_NAME_ENTRY *)sk_new_null()); | |||
480 | if (!entries) | |||
481 | goto err; | |||
482 | if (sk_STACK_OF_X509_NAME_ENTRY_push(intname,sk_push(((_STACK*) (1 ? (intname) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void*) (1 ? (entries) : (STACK_OF_X509_NAME_ENTRY*)0 ))) | |||
483 | entries)sk_push(((_STACK*) (1 ? (intname) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void*) (1 ? (entries) : (STACK_OF_X509_NAME_ENTRY*)0 ))) == 0) { | |||
484 | sk_X509_NAME_ENTRY_free(entries)sk_free(((_STACK*) (1 ? (entries) : (struct stack_st_X509_NAME_ENTRY *)0))); | |||
485 | goto err; | |||
486 | } | |||
487 | set = entry->set; | |||
488 | } | |||
489 | tmpentry = X509_NAME_ENTRY_new(); | |||
490 | if (tmpentry == NULL((void*)0)) | |||
491 | goto err; | |||
492 | tmpentry->object = OBJ_dup(entry->object); | |||
493 | if (tmpentry->object == NULL((void*)0)) | |||
494 | goto err; | |||
495 | if (!asn1_string_canon(tmpentry->value, entry->value)) | |||
496 | goto err; | |||
497 | if (entries == NULL((void*)0) /* if entry->set is bogusly -1 */ || | |||
498 | !sk_X509_NAME_ENTRY_push(entries, tmpentry)sk_push(((_STACK*) (1 ? (entries) : (struct stack_st_X509_NAME_ENTRY *)0)), ((void*) (1 ? (tmpentry) : (X509_NAME_ENTRY*)0)))) | |||
499 | goto err; | |||
500 | tmpentry = NULL((void*)0); | |||
501 | } | |||
502 | ||||
503 | /* Finally generate encoding */ | |||
504 | len = i2d_name_canon(intname, NULL((void*)0)); | |||
505 | if (len < 0) | |||
506 | goto err; | |||
507 | p = malloc(len); | |||
508 | if (p == NULL((void*)0)) | |||
509 | goto err; | |||
510 | a->canon_enc = p; | |||
511 | a->canon_enclen = len; | |||
512 | i2d_name_canon(intname, &p); | |||
513 | ret = 1; | |||
514 | ||||
515 | err: | |||
516 | if (tmpentry) | |||
517 | X509_NAME_ENTRY_free(tmpentry); | |||
518 | if (intname) | |||
519 | sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,sk_pop_free(((_STACK*) (1 ? (intname) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void (*)(void *)) ((1 ? (local_sk_X509_NAME_ENTRY_pop_free ) : (void (*)(STACK_OF_X509_NAME_ENTRY *))0)))) | |||
520 | local_sk_X509_NAME_ENTRY_pop_free)sk_pop_free(((_STACK*) (1 ? (intname) : (struct stack_st_STACK_OF_X509_NAME_ENTRY *)0)), ((void (*)(void *)) ((1 ? (local_sk_X509_NAME_ENTRY_pop_free ) : (void (*)(STACK_OF_X509_NAME_ENTRY *))0)))); | |||
521 | return ret; | |||
522 | } | |||
523 | ||||
524 | /* Bitmap of all the types of string that will be canonicalized. */ | |||
525 | ||||
526 | #define ASN1_MASK_CANON(0x2000 | 0x0800 | 0x0100 | 0x0002 | 0x0004 | 0x0010 | 0x0040 ) \ | |||
527 | (B_ASN1_UTF8STRING0x2000 | B_ASN1_BMPSTRING0x0800 | B_ASN1_UNIVERSALSTRING0x0100 \ | |||
528 | | B_ASN1_PRINTABLESTRING0x0002 | B_ASN1_T61STRING0x0004 | B_ASN1_IA5STRING0x0010 \ | |||
529 | | B_ASN1_VISIBLESTRING0x0040) | |||
530 | ||||
531 | ||||
532 | static int | |||
533 | asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) | |||
534 | { | |||
535 | unsigned char *to, *from; | |||
536 | int len, i; | |||
537 | ||||
538 | /* If type not in bitmask just copy string across */ | |||
539 | if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON(0x2000 | 0x0800 | 0x0100 | 0x0002 | 0x0004 | 0x0010 | 0x0040 ))) { | |||
540 | if (!ASN1_STRING_copy(out, in)) | |||
541 | return 0; | |||
542 | return 1; | |||
543 | } | |||
544 | ||||
545 | out->type = V_ASN1_UTF8STRING12; | |||
546 | out->length = ASN1_STRING_to_UTF8(&out->data, in); | |||
547 | if (out->length == -1) | |||
548 | return 0; | |||
549 | ||||
550 | to = out->data; | |||
551 | from = to; | |||
552 | ||||
553 | len = out->length; | |||
554 | ||||
555 | /* Convert string in place to canonical form. | |||
556 | * Ultimately we may need to handle a wider range of characters | |||
557 | * but for now ignore anything with MSB set and rely on the | |||
558 | * isspace() and tolower() functions. | |||
559 | */ | |||
560 | ||||
561 | /* Ignore leading spaces */ | |||
562 | while ((len > 0) && !(*from & 0x80) && isspace(*from)) { | |||
563 | from++; | |||
564 | len--; | |||
565 | } | |||
566 | ||||
567 | to = from + len - 1; | |||
568 | ||||
569 | /* Ignore trailing spaces */ | |||
570 | while ((len > 0) && !(*to & 0x80) && isspace(*to)) { | |||
571 | to--; | |||
572 | len--; | |||
573 | } | |||
574 | ||||
575 | to = out->data; | |||
576 | ||||
577 | i = 0; | |||
578 | while (i < len) { | |||
579 | /* If MSB set just copy across */ | |||
580 | if (*from & 0x80) { | |||
581 | *to++ = *from++; | |||
582 | i++; | |||
583 | } | |||
584 | /* Collapse multiple spaces */ | |||
585 | else if (isspace(*from)) { | |||
586 | /* Copy one space across */ | |||
587 | *to++ = ' '; | |||
588 | /* Ignore subsequent spaces. Note: don't need to | |||
589 | * check len here because we know the last | |||
590 | * character is a non-space so we can't overflow. | |||
591 | */ | |||
592 | do { | |||
593 | from++; | |||
594 | i++; | |||
595 | } while (!(*from & 0x80) && isspace(*from)); | |||
596 | } else { | |||
597 | *to++ = tolower(*from); | |||
598 | from++; | |||
599 | i++; | |||
600 | } | |||
601 | } | |||
602 | ||||
603 | out->length = to - out->data; | |||
604 | ||||
605 | return 1; | |||
606 | } | |||
607 | ||||
608 | static int | |||
609 | i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY)struct stack_st_STACK_OF_X509_NAME_ENTRY *_intname, unsigned char **in) | |||
610 | { | |||
611 | int i, len, ltmp; | |||
612 | ASN1_VALUE *v; | |||
613 | STACK_OF(ASN1_VALUE)struct stack_st_ASN1_VALUE *intname = (STACK_OF(ASN1_VALUE)struct stack_st_ASN1_VALUE *)_intname; | |||
614 | ||||
615 | len = 0; | |||
616 | for (i = 0; i < sk_ASN1_VALUE_num(intname)sk_num(((_STACK*) (1 ? (intname) : (struct stack_st_ASN1_VALUE *)0))); i++) { | |||
617 | v = sk_ASN1_VALUE_value(intname, i)((ASN1_VALUE *)sk_value(((_STACK*) (1 ? (intname) : (struct stack_st_ASN1_VALUE *)0)), (i))); | |||
618 | ltmp = ASN1_item_ex_i2d(&v, in, | |||
619 | &X509_NAME_ENTRIES_it, -1, -1); | |||
620 | if (ltmp < 0) | |||
621 | return ltmp; | |||
622 | len += ltmp; | |||
623 | } | |||
624 | return len; | |||
625 | } | |||
626 | ||||
627 | int | |||
628 | X509_NAME_set(X509_NAME **xn, X509_NAME *name) | |||
629 | { | |||
630 | if (*xn == name) | |||
631 | return *xn != NULL((void*)0); | |||
632 | if ((name = X509_NAME_dup(name)) == NULL((void*)0)) | |||
633 | return 0; | |||
634 | X509_NAME_free(*xn); | |||
635 | *xn = name; | |||
636 | return 1; | |||
637 | } | |||
638 | ||||
639 | int | |||
640 | X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, size_t *pderlen) | |||
641 | { | |||
642 | /* Make sure encoding is valid. */ | |||
643 | if (i2d_X509_NAME(nm, NULL((void*)0)) <= 0) | |||
644 | return 0; | |||
645 | if (pder != NULL((void*)0)) | |||
646 | *pder = (unsigned char *)nm->bytes->data; | |||
647 | if (pderlen != NULL((void*)0)) | |||
648 | *pderlen = nm->bytes->length; | |||
649 | return 1; | |||
650 | } |