xref: /dragonfly/crypto/libressl/crypto/asn1/x_name.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
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) STACK_OF_X509_NAME_ENTRY;
71 DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
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) *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),
94                     .field_name = "object",
95                     .item = &ASN1_OBJECT_it,
96           },
97           {
98                     .offset = 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_SEQUENCE,
106           .utype = V_ASN1_SEQUENCE,
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 *
d2i_X509_NAME_ENTRY(X509_NAME_ENTRY ** a,const unsigned char ** in,long len)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
i2d_X509_NAME_ENTRY(X509_NAME_ENTRY * a,unsigned char ** out)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 *
X509_NAME_ENTRY_new(void)128 X509_NAME_ENTRY_new(void)
129 {
130           return (X509_NAME_ENTRY *)ASN1_item_new(&X509_NAME_ENTRY_it);
131 }
132 
133 void
X509_NAME_ENTRY_free(X509_NAME_ENTRY * a)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 *
X509_NAME_ENTRY_dup(X509_NAME_ENTRY * x)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,
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_PRIMITIVE,
159           .utype = -1,
160           .templates = &X509_NAME_ENTRIES_item_tt,
161           .tcount = 0,
162           .funcs = NULL,
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,
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_PRIMITIVE,
177           .utype = -1,
178           .templates = &X509_NAME_INTERNAL_item_tt,
179           .tcount = 0,
180           .funcs = NULL,
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,
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_EXTERN,
203           .utype = V_ASN1_SEQUENCE,
204           .templates = NULL,
205           .tcount = 0,
206           .funcs = &x509_name_ff,
207           .size = 0,
208           .sname = "X509_NAME",
209 };
210 
211 X509_NAME *
d2i_X509_NAME(X509_NAME ** a,const unsigned char ** in,long len)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
i2d_X509_NAME(X509_NAME * a,unsigned char ** out)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 *
X509_NAME_new(void)225 X509_NAME_new(void)
226 {
227           return (X509_NAME *)ASN1_item_new(&X509_NAME_it);
228 }
229 
230 void
X509_NAME_free(X509_NAME * a)231 X509_NAME_free(X509_NAME *a)
232 {
233           ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_it);
234 }
235 
236 X509_NAME *
X509_NAME_dup(X509_NAME * x)237 X509_NAME_dup(X509_NAME *x)
238 {
239           return ASN1_item_dup(&X509_NAME_it, x);
240 }
241 
242 static int
x509_name_ex_new(ASN1_VALUE ** val,const ASN1_ITEM * it)243 x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
244 {
245           X509_NAME *ret = NULL;
246 
247           ret = malloc(sizeof(X509_NAME));
248           if (!ret)
249                     goto memerr;
250           if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
251                     goto memerr;
252           if ((ret->bytes = BUF_MEM_new()) == NULL)
253                     goto memerr;
254           ret->canon_enc = NULL;
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);
262           if (ret) {
263                     if (ret->entries)
264                               sk_X509_NAME_ENTRY_free(ret->entries);
265                     free(ret);
266           }
267           return 0;
268 }
269 
270 static void
x509_name_ex_free(ASN1_VALUE ** pval,const ASN1_ITEM * it)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);
281           free(a->canon_enc);
282           free(a);
283           *pval = NULL;
284 }
285 
286 static int
x509_name_ex_d2i(ASN1_VALUE ** val,const unsigned char ** in,long len,const ASN1_ITEM * it,int tag,int aclass,char opt,ASN1_TLC * ctx)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) *s;
293                     ASN1_VALUE *a;
294           } intname = {NULL};
295           union {
296                     X509_NAME *x;
297                     ASN1_VALUE *a;
298           } nm = {NULL};
299           int i, j, ret;
300           STACK_OF(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);
313           if (!x509_name_ex_new(&nm.a, NULL))
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); i++) {
322                     entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
323                     for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
324                               entry = sk_X509_NAME_ENTRY_value(entries, j);
325                               entry->set = i;
326                               if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
327                                         goto err;
328                     }
329                     sk_X509_NAME_ENTRY_free(entries);
330           }
331           sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
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)
342                     X509_NAME_free(nm.x);
343           ASN1error(ERR_R_NESTED_ASN1_ERROR);
344           return 0;
345 }
346 
347 static int
x509_name_ex_i2d(ASN1_VALUE ** val,unsigned char ** out,const ASN1_ITEM * it,int tag,int aclass)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) {
364                     memcpy(*out, a->bytes->data, ret);
365                     *out += ret;
366           }
367           return ret;
368 }
369 
370 static void
local_sk_X509_NAME_ENTRY_free(STACK_OF (X509_NAME_ENTRY)* ne)371 local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
372 {
373           sk_X509_NAME_ENTRY_free(ne);
374 }
375 
376 static void
local_sk_X509_NAME_ENTRY_pop_free(STACK_OF (X509_NAME_ENTRY)* ne)377 local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
378 {
379           sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
380 }
381 
382 static int
x509_name_encode(X509_NAME * a)383 x509_name_encode(X509_NAME *a)
384 {
385           union {
386                     STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
387                     ASN1_VALUE *a;
388           } intname = {NULL};
389           int len;
390           unsigned char *p;
391           STACK_OF(X509_NAME_ENTRY) *entries = NULL;
392           X509_NAME_ENTRY *entry;
393           int i, set = -1;
394 
395           intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
396           if (!intname.s)
397                     goto memerr;
398           for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
399                     entry = sk_X509_NAME_ENTRY_value(a->entries, i);
400                     if (entry->set != set) {
401                               entries = sk_X509_NAME_ENTRY_new_null();
402                               if (!entries)
403                                         goto memerr;
404                               if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
405                                   entries))
406                                         goto memerr;
407                               set = entry->set;
408                     }
409                     if (entries == NULL /* if entry->set is bogusly -1 */ ||
410                         !sk_X509_NAME_ENTRY_push(entries, entry))
411                               goto memerr;
412           }
413           len = ASN1_item_ex_i2d(&intname.a, NULL,
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,
421               local_sk_X509_NAME_ENTRY_free);
422           a->modified = 0;
423           return len;
424 
425  memerr:
426           sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
427               local_sk_X509_NAME_ENTRY_free);
428           ASN1error(ERR_R_MALLOC_FAILURE);
429           return -1;
430 }
431 
432 static int
x509_name_ex_print(BIO * out,ASN1_VALUE ** pval,int indent,const char * fname,const ASN1_PCTX * pctx)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
x509_name_canon(X509_NAME * a)456 x509_name_canon(X509_NAME *a)
457 {
458           unsigned char *p;
459           STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
460           STACK_OF(X509_NAME_ENTRY) *entries = NULL;
461           X509_NAME_ENTRY *entry, *tmpentry = NULL;
462           int i, len, set = -1, ret = 0;
463 
464           if (a->canon_enc) {
465                     free(a->canon_enc);
466                     a->canon_enc = NULL;
467           }
468           /* Special case: empty X509_NAME => null encoding */
469           if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
470                     a->canon_enclen = 0;
471                     return 1;
472           }
473           intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
474           if (!intname)
475                     goto err;
476           for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
477                     entry = sk_X509_NAME_ENTRY_value(a->entries, i);
478                     if (entry->set != set) {
479                               entries = sk_X509_NAME_ENTRY_new_null();
480                               if (!entries)
481                                         goto err;
482                               if (sk_STACK_OF_X509_NAME_ENTRY_push(intname,
483                                   entries) == 0) {
484                                         sk_X509_NAME_ENTRY_free(entries);
485                                         goto err;
486                               }
487                               set = entry->set;
488                     }
489                     tmpentry = X509_NAME_ENTRY_new();
490                     if (tmpentry == NULL)
491                               goto err;
492                     tmpentry->object = OBJ_dup(entry->object);
493                     if (tmpentry->object == NULL)
494                               goto err;
495                     if (!asn1_string_canon(tmpentry->value, entry->value))
496                               goto err;
497                     if (entries == NULL /* if entry->set is bogusly -1 */ ||
498                         !sk_X509_NAME_ENTRY_push(entries, tmpentry))
499                               goto err;
500                     tmpentry = NULL;
501           }
502 
503           /* Finally generate encoding */
504           len = i2d_name_canon(intname, NULL);
505           if (len < 0)
506                     goto err;
507           p = malloc(len);
508           if (p == NULL)
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,
520                         local_sk_X509_NAME_ENTRY_pop_free);
521           return ret;
522 }
523 
524 /* Bitmap of all the types of string that will be canonicalized. */
525 
526 #define ASN1_MASK_CANON       \
527           (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
528           | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
529           | B_ASN1_VISIBLESTRING)
530 
531 
532 static int
asn1_string_canon(ASN1_STRING * out,ASN1_STRING * in)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)) {
540                     if (!ASN1_STRING_copy(out, in))
541                               return 0;
542                     return 1;
543           }
544 
545           out->type = V_ASN1_UTF8STRING;
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
i2d_name_canon(STACK_OF (STACK_OF_X509_NAME_ENTRY)* _intname,unsigned char ** in)609 i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, unsigned char **in)
610 {
611           int i, len, ltmp;
612           ASN1_VALUE *v;
613           STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
614 
615           len = 0;
616           for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
617                     v = sk_ASN1_VALUE_value(intname, 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
X509_NAME_set(X509_NAME ** xn,X509_NAME * name)628 X509_NAME_set(X509_NAME **xn, X509_NAME *name)
629 {
630           if (*xn == name)
631                     return *xn != NULL;
632           if ((name = X509_NAME_dup(name)) == NULL)
633                     return 0;
634           X509_NAME_free(*xn);
635           *xn = name;
636           return 1;
637 }
638 
639 int
X509_NAME_get0_der(X509_NAME * nm,const unsigned char ** pder,size_t * pderlen)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) <= 0)
644                     return 0;
645           if (pder != NULL)
646                     *pder = (unsigned char *)nm->bytes->data;
647           if (pderlen != NULL)
648                     *pderlen = nm->bytes->length;
649           return 1;
650 }
651