155714Skris/* crypto/asn1/x_name.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8280304Sjkim *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15280304Sjkim *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22280304Sjkim *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40280304Sjkim *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52280304Sjkim *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
60238405Sjkim#include <ctype.h>
6155714Skris#include "cryptlib.h"
62109998Smarkm#include <openssl/asn1t.h>
6355714Skris#include <openssl/x509.h>
64238405Sjkim#include "asn1_locl.h"
6555714Skris
66238405Sjkimtypedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
67238405SjkimDECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
6855714Skris
69298999Sjkim/*
70298999Sjkim * Maximum length of X509_NAME: much larger than anything we should
71298999Sjkim * ever see in practice.
72298999Sjkim */
73298999Sjkim
74298999Sjkim#define X509_NAME_MAX (1024 * 1024)
75298999Sjkim
76238405Sjkimstatic int x509_name_ex_d2i(ASN1_VALUE **val,
77280304Sjkim                            const unsigned char **in, long len,
78280304Sjkim                            const ASN1_ITEM *it,
79280304Sjkim                            int tag, int aclass, char opt, ASN1_TLC *ctx);
80238405Sjkim
81238405Sjkimstatic int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
82280304Sjkim                            const ASN1_ITEM *it, int tag, int aclass);
83109998Smarkmstatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
84109998Smarkmstatic void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
8555714Skris
86109998Smarkmstatic int x509_name_encode(X509_NAME *a);
87238405Sjkimstatic int x509_name_canon(X509_NAME *a);
88238405Sjkimstatic int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
89280304Sjkimstatic int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
90280304Sjkim                          unsigned char **in);
9155714Skris
92238405Sjkimstatic int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
93280304Sjkim                              int indent,
94280304Sjkim                              const char *fname, const ASN1_PCTX *pctx);
95238405Sjkim
96109998SmarkmASN1_SEQUENCE(X509_NAME_ENTRY) = {
97280304Sjkim        ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
98280304Sjkim        ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
99109998Smarkm} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
10055714Skris
101109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
102109998SmarkmIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
10355714Skris
104280304Sjkim/*
105280304Sjkim * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
106280304Sjkim * declare two template wrappers for this
107109998Smarkm */
10855714Skris
109109998SmarkmASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
110280304Sjkim        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
111109998SmarkmASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
11255714Skris
113109998SmarkmASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
114280304Sjkim        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
115109998SmarkmASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
11655714Skris
117280304Sjkim/*
118280304Sjkim * Normally that's where it would end: we'd have two nested STACK structures
119109998Smarkm * representing the ASN1. Unfortunately X509_NAME uses a completely different
120280304Sjkim * form and caches encodings so we have to process the internal form and
121280304Sjkim * convert to the external form.
122109998Smarkm */
12355714Skris
124109998Smarkmconst ASN1_EXTERN_FUNCS x509_name_ff = {
125280304Sjkim    NULL,
126280304Sjkim    x509_name_ex_new,
127280304Sjkim    x509_name_ex_free,
128280304Sjkim    0,                          /* Default clear behaviour is OK */
129280304Sjkim    x509_name_ex_d2i,
130280304Sjkim    x509_name_ex_i2d,
131280304Sjkim    x509_name_ex_print
132109998Smarkm};
13355714Skris
134280304SjkimIMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
13555714Skris
136109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
137280304Sjkim
138109998SmarkmIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
13955714Skris
140109998Smarkmstatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
141109998Smarkm{
142280304Sjkim    X509_NAME *ret = NULL;
143280304Sjkim    ret = OPENSSL_malloc(sizeof(X509_NAME));
144280304Sjkim    if (!ret)
145280304Sjkim        goto memerr;
146280304Sjkim    if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
147280304Sjkim        goto memerr;
148280304Sjkim    if ((ret->bytes = BUF_MEM_new()) == NULL)
149280304Sjkim        goto memerr;
150280304Sjkim    ret->canon_enc = NULL;
151280304Sjkim    ret->canon_enclen = 0;
152280304Sjkim    ret->modified = 1;
153280304Sjkim    *val = (ASN1_VALUE *)ret;
154280304Sjkim    return 1;
155109998Smarkm
156109998Smarkm memerr:
157280304Sjkim    ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
158280304Sjkim    if (ret) {
159280304Sjkim        if (ret->entries)
160280304Sjkim            sk_X509_NAME_ENTRY_free(ret->entries);
161280304Sjkim        OPENSSL_free(ret);
162280304Sjkim    }
163280304Sjkim    return 0;
164109998Smarkm}
16555714Skris
166109998Smarkmstatic void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
167109998Smarkm{
168280304Sjkim    X509_NAME *a;
169280304Sjkim    if (!pval || !*pval)
170280304Sjkim        return;
171280304Sjkim    a = (X509_NAME *)*pval;
17255714Skris
173280304Sjkim    BUF_MEM_free(a->bytes);
174280304Sjkim    sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
175280304Sjkim    if (a->canon_enc)
176280304Sjkim        OPENSSL_free(a->canon_enc);
177280304Sjkim    OPENSSL_free(a);
178280304Sjkim    *pval = NULL;
179109998Smarkm}
18055714Skris
181238405Sjkimstatic int x509_name_ex_d2i(ASN1_VALUE **val,
182280304Sjkim                            const unsigned char **in, long len,
183280304Sjkim                            const ASN1_ITEM *it, int tag, int aclass,
184280304Sjkim                            char opt, ASN1_TLC *ctx)
185109998Smarkm{
186280304Sjkim    const unsigned char *p = *in, *q;
187280304Sjkim    union {
188280304Sjkim        STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
189280304Sjkim        ASN1_VALUE *a;
190280304Sjkim    } intname = {
191280304Sjkim        NULL
192280304Sjkim    };
193280304Sjkim    union {
194280304Sjkim        X509_NAME *x;
195280304Sjkim        ASN1_VALUE *a;
196280304Sjkim    } nm = {
197280304Sjkim        NULL
198280304Sjkim    };
199280304Sjkim    int i, j, ret;
200280304Sjkim    STACK_OF(X509_NAME_ENTRY) *entries;
201280304Sjkim    X509_NAME_ENTRY *entry;
202306196Sjkim    if (len > X509_NAME_MAX)
203306196Sjkim        len = X509_NAME_MAX;
204280304Sjkim    q = p;
20555714Skris
206280304Sjkim    /* Get internal representation of Name */
207280304Sjkim    ret = ASN1_item_ex_d2i(&intname.a,
208280304Sjkim                           &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
209280304Sjkim                           tag, aclass, opt, ctx);
21055714Skris
211280304Sjkim    if (ret <= 0)
212280304Sjkim        return ret;
213109998Smarkm
214280304Sjkim    if (*val)
215280304Sjkim        x509_name_ex_free(val, NULL);
216280304Sjkim    if (!x509_name_ex_new(&nm.a, NULL))
217280304Sjkim        goto err;
218280304Sjkim    /* We've decoded it: now cache encoding */
219280304Sjkim    if (!BUF_MEM_grow(nm.x->bytes, p - q))
220280304Sjkim        goto err;
221280304Sjkim    memcpy(nm.x->bytes->data, q, p - q);
222280304Sjkim
223280304Sjkim    /* Convert internal representation to X509_NAME structure */
224280304Sjkim    for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
225280304Sjkim        entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
226280304Sjkim        for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
227280304Sjkim            entry = sk_X509_NAME_ENTRY_value(entries, j);
228280304Sjkim            entry->set = i;
229280304Sjkim            if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
230280304Sjkim                goto err;
231280304Sjkim        }
232280304Sjkim        sk_X509_NAME_ENTRY_free(entries);
233280304Sjkim    }
234280304Sjkim    sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
235280304Sjkim    ret = x509_name_canon(nm.x);
236280304Sjkim    if (!ret)
237280304Sjkim        goto err;
238280304Sjkim    nm.x->modified = 0;
239280304Sjkim    *val = nm.a;
240280304Sjkim    *in = p;
241280304Sjkim    return ret;
242280304Sjkim err:
243280304Sjkim    if (nm.x != NULL)
244280304Sjkim        X509_NAME_free(nm.x);
245280304Sjkim    ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
246280304Sjkim    return 0;
247109998Smarkm}
24855714Skris
249280304Sjkimstatic int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
250280304Sjkim                            const ASN1_ITEM *it, int tag, int aclass)
251109998Smarkm{
252280304Sjkim    int ret;
253280304Sjkim    X509_NAME *a = (X509_NAME *)*val;
254280304Sjkim    if (a->modified) {
255280304Sjkim        ret = x509_name_encode(a);
256280304Sjkim        if (ret < 0)
257280304Sjkim            return ret;
258280304Sjkim        ret = x509_name_canon(a);
259280304Sjkim        if (ret < 0)
260280304Sjkim            return ret;
261280304Sjkim    }
262280304Sjkim    ret = a->bytes->length;
263280304Sjkim    if (out != NULL) {
264280304Sjkim        memcpy(*out, a->bytes->data, ret);
265280304Sjkim        *out += ret;
266280304Sjkim    }
267280304Sjkim    return ret;
268109998Smarkm}
26955714Skris
270238405Sjkimstatic void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
271280304Sjkim{
272280304Sjkim    sk_X509_NAME_ENTRY_free(ne);
273280304Sjkim}
274238405Sjkim
275238405Sjkimstatic void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
276280304Sjkim{
277280304Sjkim    sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
278280304Sjkim}
279238405Sjkim
280109998Smarkmstatic int x509_name_encode(X509_NAME *a)
281109998Smarkm{
282280304Sjkim    union {
283280304Sjkim        STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
284280304Sjkim        ASN1_VALUE *a;
285280304Sjkim    } intname = {
286280304Sjkim        NULL
287280304Sjkim    };
288280304Sjkim    int len;
289280304Sjkim    unsigned char *p;
290280304Sjkim    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
291280304Sjkim    X509_NAME_ENTRY *entry;
292280304Sjkim    int i, set = -1;
293280304Sjkim    intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
294280304Sjkim    if (!intname.s)
295280304Sjkim        goto memerr;
296280304Sjkim    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
297280304Sjkim        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
298280304Sjkim        if (entry->set != set) {
299280304Sjkim            entries = sk_X509_NAME_ENTRY_new_null();
300280304Sjkim            if (!entries)
301280304Sjkim                goto memerr;
302280304Sjkim            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
303280304Sjkim                goto memerr;
304280304Sjkim            set = entry->set;
305280304Sjkim        }
306280304Sjkim        if (!sk_X509_NAME_ENTRY_push(entries, entry))
307280304Sjkim            goto memerr;
308280304Sjkim    }
309280304Sjkim    len = ASN1_item_ex_i2d(&intname.a, NULL,
310280304Sjkim                           ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
311280304Sjkim    if (!BUF_MEM_grow(a->bytes, len))
312280304Sjkim        goto memerr;
313280304Sjkim    p = (unsigned char *)a->bytes->data;
314280304Sjkim    ASN1_item_ex_i2d(&intname.a,
315280304Sjkim                     &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
316280304Sjkim    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
317280304Sjkim                                         local_sk_X509_NAME_ENTRY_free);
318280304Sjkim    a->modified = 0;
319280304Sjkim    return len;
320280304Sjkim memerr:
321280304Sjkim    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
322280304Sjkim                                         local_sk_X509_NAME_ENTRY_free);
323280304Sjkim    ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
324280304Sjkim    return -1;
325109998Smarkm}
32655714Skris
327238405Sjkimstatic int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
328280304Sjkim                              int indent,
329280304Sjkim                              const char *fname, const ASN1_PCTX *pctx)
330280304Sjkim{
331280304Sjkim    if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
332280304Sjkim                           indent, pctx->nm_flags) <= 0)
333280304Sjkim        return 0;
334280304Sjkim    return 2;
335280304Sjkim}
33655714Skris
337280304Sjkim/*
338280304Sjkim * This function generates the canonical encoding of the Name structure. In
339280304Sjkim * it all strings are converted to UTF8, leading, trailing and multiple
340280304Sjkim * spaces collapsed, converted to lower case and the leading SEQUENCE header
341280304Sjkim * removed. In future we could also normalize the UTF8 too. By doing this
342280304Sjkim * comparison of Name structures can be rapidly perfomed by just using
343280304Sjkim * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
344280304Sjkim * constraints of type dirName can also be checked with a simple memcmp().
345238405Sjkim */
346238405Sjkim
347238405Sjkimstatic int x509_name_canon(X509_NAME *a)
348280304Sjkim{
349280304Sjkim    unsigned char *p;
350280304Sjkim    STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
351280304Sjkim    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
352280304Sjkim    X509_NAME_ENTRY *entry, *tmpentry = NULL;
353280304Sjkim    int i, set = -1, ret = 0;
354238405Sjkim
355280304Sjkim    if (a->canon_enc) {
356280304Sjkim        OPENSSL_free(a->canon_enc);
357280304Sjkim        a->canon_enc = NULL;
358280304Sjkim    }
359280304Sjkim    /* Special case: empty X509_NAME => null encoding */
360280304Sjkim    if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
361280304Sjkim        a->canon_enclen = 0;
362280304Sjkim        return 1;
363280304Sjkim    }
364280304Sjkim    intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
365280304Sjkim    if (!intname)
366280304Sjkim        goto err;
367280304Sjkim    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
368280304Sjkim        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
369280304Sjkim        if (entry->set != set) {
370280304Sjkim            entries = sk_X509_NAME_ENTRY_new_null();
371280304Sjkim            if (!entries)
372280304Sjkim                goto err;
373280304Sjkim            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
374280304Sjkim                goto err;
375280304Sjkim            set = entry->set;
376280304Sjkim        }
377280304Sjkim        tmpentry = X509_NAME_ENTRY_new();
378280304Sjkim        if (!tmpentry)
379280304Sjkim            goto err;
380280304Sjkim        tmpentry->object = OBJ_dup(entry->object);
381280304Sjkim        if (!asn1_string_canon(tmpentry->value, entry->value))
382280304Sjkim            goto err;
383280304Sjkim        if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
384280304Sjkim            goto err;
385280304Sjkim        tmpentry = NULL;
386280304Sjkim    }
387238405Sjkim
388280304Sjkim    /* Finally generate encoding */
389238405Sjkim
390280304Sjkim    a->canon_enclen = i2d_name_canon(intname, NULL);
391238405Sjkim
392280304Sjkim    p = OPENSSL_malloc(a->canon_enclen);
393238405Sjkim
394280304Sjkim    if (!p)
395280304Sjkim        goto err;
396238405Sjkim
397280304Sjkim    a->canon_enc = p;
398238405Sjkim
399280304Sjkim    i2d_name_canon(intname, &p);
400238405Sjkim
401280304Sjkim    ret = 1;
402238405Sjkim
403280304Sjkim err:
404238405Sjkim
405280304Sjkim    if (tmpentry)
406280304Sjkim        X509_NAME_ENTRY_free(tmpentry);
407280304Sjkim    if (intname)
408280304Sjkim        sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
409280304Sjkim                                             local_sk_X509_NAME_ENTRY_pop_free);
410280304Sjkim    return ret;
411280304Sjkim}
412238405Sjkim
413238405Sjkim/* Bitmap of all the types of string that will be canonicalized. */
414238405Sjkim
415280304Sjkim#define ASN1_MASK_CANON \
416280304Sjkim        (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
417280304Sjkim        | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
418280304Sjkim        | B_ASN1_VISIBLESTRING)
419238405Sjkim
420238405Sjkimstatic int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
421280304Sjkim{
422280304Sjkim    unsigned char *to, *from;
423280304Sjkim    int len, i;
424238405Sjkim
425280304Sjkim    /* If type not in bitmask just copy string across */
426280304Sjkim    if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
427280304Sjkim        if (!ASN1_STRING_copy(out, in))
428280304Sjkim            return 0;
429280304Sjkim        return 1;
430280304Sjkim    }
431238405Sjkim
432280304Sjkim    out->type = V_ASN1_UTF8STRING;
433280304Sjkim    out->length = ASN1_STRING_to_UTF8(&out->data, in);
434280304Sjkim    if (out->length == -1)
435280304Sjkim        return 0;
436238405Sjkim
437280304Sjkim    to = out->data;
438280304Sjkim    from = to;
439238405Sjkim
440280304Sjkim    len = out->length;
441238405Sjkim
442280304Sjkim    /*
443280304Sjkim     * Convert string in place to canonical form. Ultimately we may need to
444280304Sjkim     * handle a wider range of characters but for now ignore anything with
445280304Sjkim     * MSB set and rely on the isspace() and tolower() functions.
446280304Sjkim     */
447238405Sjkim
448280304Sjkim    /* Ignore leading spaces */
449280304Sjkim    while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
450280304Sjkim        from++;
451280304Sjkim        len--;
452280304Sjkim    }
453238405Sjkim
454280304Sjkim    to = from + len - 1;
455238405Sjkim
456280304Sjkim    /* Ignore trailing spaces */
457280304Sjkim    while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
458280304Sjkim        to--;
459280304Sjkim        len--;
460280304Sjkim    }
461238405Sjkim
462280304Sjkim    to = out->data;
463238405Sjkim
464280304Sjkim    i = 0;
465280304Sjkim    while (i < len) {
466280304Sjkim        /* If MSB set just copy across */
467280304Sjkim        if (*from & 0x80) {
468280304Sjkim            *to++ = *from++;
469280304Sjkim            i++;
470280304Sjkim        }
471280304Sjkim        /* Collapse multiple spaces */
472280304Sjkim        else if (isspace(*from)) {
473280304Sjkim            /* Copy one space across */
474280304Sjkim            *to++ = ' ';
475280304Sjkim            /*
476280304Sjkim             * Ignore subsequent spaces. Note: don't need to check len here
477280304Sjkim             * because we know the last character is a non-space so we can't
478280304Sjkim             * overflow.
479280304Sjkim             */
480280304Sjkim            do {
481280304Sjkim                from++;
482280304Sjkim                i++;
483280304Sjkim            }
484280304Sjkim            while (!(*from & 0x80) && isspace(*from));
485280304Sjkim        } else {
486280304Sjkim            *to++ = tolower(*from);
487280304Sjkim            from++;
488280304Sjkim            i++;
489280304Sjkim        }
490280304Sjkim    }
491238405Sjkim
492280304Sjkim    out->length = to - out->data;
493238405Sjkim
494280304Sjkim    return 1;
495238405Sjkim
496280304Sjkim}
497238405Sjkim
498280304Sjkimstatic int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
499280304Sjkim                          unsigned char **in)
500280304Sjkim{
501280304Sjkim    int i, len, ltmp;
502280304Sjkim    ASN1_VALUE *v;
503280304Sjkim    STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
504238405Sjkim
505280304Sjkim    len = 0;
506280304Sjkim    for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
507280304Sjkim        v = sk_ASN1_VALUE_value(intname, i);
508280304Sjkim        ltmp = ASN1_item_ex_i2d(&v, in,
509280304Sjkim                                ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
510280304Sjkim        if (ltmp < 0)
511280304Sjkim            return ltmp;
512280304Sjkim        len += ltmp;
513280304Sjkim    }
514280304Sjkim    return len;
515280304Sjkim}
516238405Sjkim
51755714Skrisint X509_NAME_set(X509_NAME **xn, X509_NAME *name)
518280304Sjkim{
519280304Sjkim    X509_NAME *in;
52055714Skris
521280304Sjkim    if (!xn || !name)
522280304Sjkim        return (0);
52355714Skris
524280304Sjkim    if (*xn != name) {
525280304Sjkim        in = X509_NAME_dup(name);
526280304Sjkim        if (in != NULL) {
527280304Sjkim            X509_NAME_free(*xn);
528280304Sjkim            *xn = in;
529280304Sjkim        }
530280304Sjkim    }
531280304Sjkim    return (*xn != NULL);
532280304Sjkim}
533280304Sjkim
53455714SkrisIMPLEMENT_STACK_OF(X509_NAME_ENTRY)
535280304Sjkim
53655714SkrisIMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
537