1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <stdio.h>
11e1051a39Sopenharmony_ci#include "crypto/ctype.h"
12e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
13e1051a39Sopenharmony_ci#include <openssl/asn1t.h>
14e1051a39Sopenharmony_ci#include <openssl/x509.h>
15e1051a39Sopenharmony_ci#include "crypto/x509.h"
16e1051a39Sopenharmony_ci#include "crypto/asn1.h"
17e1051a39Sopenharmony_ci#include "x509_local.h"
18e1051a39Sopenharmony_ci
19e1051a39Sopenharmony_ci/*
20e1051a39Sopenharmony_ci * Maximum length of X509_NAME: much larger than anything we should
21e1051a39Sopenharmony_ci * ever see in practice.
22e1051a39Sopenharmony_ci */
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci#define X509_NAME_MAX (1024 * 1024)
25e1051a39Sopenharmony_ci
26e1051a39Sopenharmony_cistatic int x509_name_ex_d2i(ASN1_VALUE **val,
27e1051a39Sopenharmony_ci                            const unsigned char **in, long len,
28e1051a39Sopenharmony_ci                            const ASN1_ITEM *it,
29e1051a39Sopenharmony_ci                            int tag, int aclass, char opt, ASN1_TLC *ctx);
30e1051a39Sopenharmony_ci
31e1051a39Sopenharmony_cistatic int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out,
32e1051a39Sopenharmony_ci                            const ASN1_ITEM *it, int tag, int aclass);
33e1051a39Sopenharmony_cistatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
34e1051a39Sopenharmony_cistatic void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_cistatic int x509_name_encode(X509_NAME *a);
37e1051a39Sopenharmony_cistatic int x509_name_canon(X509_NAME *a);
38e1051a39Sopenharmony_cistatic int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in);
39e1051a39Sopenharmony_cistatic int i2d_name_canon(const STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
40e1051a39Sopenharmony_ci                          unsigned char **in);
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_cistatic int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval,
43e1051a39Sopenharmony_ci                              int indent,
44e1051a39Sopenharmony_ci                              const char *fname, const ASN1_PCTX *pctx);
45e1051a39Sopenharmony_ci
46e1051a39Sopenharmony_ciASN1_SEQUENCE(X509_NAME_ENTRY) = {
47e1051a39Sopenharmony_ci        ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
48e1051a39Sopenharmony_ci        ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
49e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
52e1051a39Sopenharmony_ciIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
53e1051a39Sopenharmony_ci
54e1051a39Sopenharmony_ci/*
55e1051a39Sopenharmony_ci * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
56e1051a39Sopenharmony_ci * declare two template wrappers for this
57e1051a39Sopenharmony_ci */
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ciASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
60e1051a39Sopenharmony_ci        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
61e1051a39Sopenharmony_cistatic_ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_ciASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
64e1051a39Sopenharmony_ci        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
65e1051a39Sopenharmony_cistatic_ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
66e1051a39Sopenharmony_ci
67e1051a39Sopenharmony_ci/*
68e1051a39Sopenharmony_ci * Normally that's where it would end: we'd have two nested STACK structures
69e1051a39Sopenharmony_ci * representing the ASN1. Unfortunately X509_NAME uses a completely different
70e1051a39Sopenharmony_ci * form and caches encodings so we have to process the internal form and
71e1051a39Sopenharmony_ci * convert to the external form.
72e1051a39Sopenharmony_ci */
73e1051a39Sopenharmony_ci
74e1051a39Sopenharmony_cistatic const ASN1_EXTERN_FUNCS x509_name_ff = {
75e1051a39Sopenharmony_ci    NULL,
76e1051a39Sopenharmony_ci    x509_name_ex_new,
77e1051a39Sopenharmony_ci    x509_name_ex_free,
78e1051a39Sopenharmony_ci    0,                          /* Default clear behaviour is OK */
79e1051a39Sopenharmony_ci    x509_name_ex_d2i,
80e1051a39Sopenharmony_ci    x509_name_ex_i2d,
81e1051a39Sopenharmony_ci    x509_name_ex_print
82e1051a39Sopenharmony_ci};
83e1051a39Sopenharmony_ci
84e1051a39Sopenharmony_ciIMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
85e1051a39Sopenharmony_ci
86e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
87e1051a39Sopenharmony_ci
88e1051a39Sopenharmony_ciIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
89e1051a39Sopenharmony_ci
90e1051a39Sopenharmony_cistatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
91e1051a39Sopenharmony_ci{
92e1051a39Sopenharmony_ci    X509_NAME *ret = OPENSSL_zalloc(sizeof(*ret));
93e1051a39Sopenharmony_ci
94e1051a39Sopenharmony_ci    if (ret == NULL)
95e1051a39Sopenharmony_ci        goto memerr;
96e1051a39Sopenharmony_ci    if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
97e1051a39Sopenharmony_ci        goto memerr;
98e1051a39Sopenharmony_ci    if ((ret->bytes = BUF_MEM_new()) == NULL)
99e1051a39Sopenharmony_ci        goto memerr;
100e1051a39Sopenharmony_ci    ret->modified = 1;
101e1051a39Sopenharmony_ci    *val = (ASN1_VALUE *)ret;
102e1051a39Sopenharmony_ci    return 1;
103e1051a39Sopenharmony_ci
104e1051a39Sopenharmony_ci memerr:
105e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
106e1051a39Sopenharmony_ci    if (ret) {
107e1051a39Sopenharmony_ci        sk_X509_NAME_ENTRY_free(ret->entries);
108e1051a39Sopenharmony_ci        OPENSSL_free(ret);
109e1051a39Sopenharmony_ci    }
110e1051a39Sopenharmony_ci    return 0;
111e1051a39Sopenharmony_ci}
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_cistatic void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
114e1051a39Sopenharmony_ci{
115e1051a39Sopenharmony_ci    X509_NAME *a;
116e1051a39Sopenharmony_ci
117e1051a39Sopenharmony_ci    if (pval == NULL || *pval == NULL)
118e1051a39Sopenharmony_ci        return;
119e1051a39Sopenharmony_ci    a = (X509_NAME *)*pval;
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci    BUF_MEM_free(a->bytes);
122e1051a39Sopenharmony_ci    sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
123e1051a39Sopenharmony_ci    OPENSSL_free(a->canon_enc);
124e1051a39Sopenharmony_ci    OPENSSL_free(a);
125e1051a39Sopenharmony_ci    *pval = NULL;
126e1051a39Sopenharmony_ci}
127e1051a39Sopenharmony_ci
128e1051a39Sopenharmony_cistatic void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
129e1051a39Sopenharmony_ci{
130e1051a39Sopenharmony_ci    sk_X509_NAME_ENTRY_free(ne);
131e1051a39Sopenharmony_ci}
132e1051a39Sopenharmony_ci
133e1051a39Sopenharmony_cistatic void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
134e1051a39Sopenharmony_ci{
135e1051a39Sopenharmony_ci    sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
136e1051a39Sopenharmony_ci}
137e1051a39Sopenharmony_ci
138e1051a39Sopenharmony_cistatic int x509_name_ex_d2i(ASN1_VALUE **val,
139e1051a39Sopenharmony_ci                            const unsigned char **in, long len,
140e1051a39Sopenharmony_ci                            const ASN1_ITEM *it, int tag, int aclass,
141e1051a39Sopenharmony_ci                            char opt, ASN1_TLC *ctx)
142e1051a39Sopenharmony_ci{
143e1051a39Sopenharmony_ci    const unsigned char *p = *in, *q;
144e1051a39Sopenharmony_ci    union {
145e1051a39Sopenharmony_ci        STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
146e1051a39Sopenharmony_ci        ASN1_VALUE *a;
147e1051a39Sopenharmony_ci    } intname = {
148e1051a39Sopenharmony_ci        NULL
149e1051a39Sopenharmony_ci    };
150e1051a39Sopenharmony_ci    union {
151e1051a39Sopenharmony_ci        X509_NAME *x;
152e1051a39Sopenharmony_ci        ASN1_VALUE *a;
153e1051a39Sopenharmony_ci    } nm = {
154e1051a39Sopenharmony_ci        NULL
155e1051a39Sopenharmony_ci    };
156e1051a39Sopenharmony_ci    int i, j, ret;
157e1051a39Sopenharmony_ci    STACK_OF(X509_NAME_ENTRY) *entries;
158e1051a39Sopenharmony_ci    X509_NAME_ENTRY *entry;
159e1051a39Sopenharmony_ci
160e1051a39Sopenharmony_ci    if (len > X509_NAME_MAX)
161e1051a39Sopenharmony_ci        len = X509_NAME_MAX;
162e1051a39Sopenharmony_ci    q = p;
163e1051a39Sopenharmony_ci
164e1051a39Sopenharmony_ci    /* Get internal representation of Name */
165e1051a39Sopenharmony_ci    ret = ASN1_item_ex_d2i(&intname.a,
166e1051a39Sopenharmony_ci                           &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
167e1051a39Sopenharmony_ci                           tag, aclass, opt, ctx);
168e1051a39Sopenharmony_ci
169e1051a39Sopenharmony_ci    if (ret <= 0)
170e1051a39Sopenharmony_ci        return ret;
171e1051a39Sopenharmony_ci
172e1051a39Sopenharmony_ci    if (*val)
173e1051a39Sopenharmony_ci        x509_name_ex_free(val, NULL);
174e1051a39Sopenharmony_ci    if (!x509_name_ex_new(&nm.a, NULL))
175e1051a39Sopenharmony_ci        goto err;
176e1051a39Sopenharmony_ci    /* We've decoded it: now cache encoding */
177e1051a39Sopenharmony_ci    if (!BUF_MEM_grow(nm.x->bytes, p - q))
178e1051a39Sopenharmony_ci        goto err;
179e1051a39Sopenharmony_ci    memcpy(nm.x->bytes->data, q, p - q);
180e1051a39Sopenharmony_ci
181e1051a39Sopenharmony_ci    /* Convert internal representation to X509_NAME structure */
182e1051a39Sopenharmony_ci    for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
183e1051a39Sopenharmony_ci        entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
184e1051a39Sopenharmony_ci        for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
185e1051a39Sopenharmony_ci            entry = sk_X509_NAME_ENTRY_value(entries, j);
186e1051a39Sopenharmony_ci            entry->set = i;
187e1051a39Sopenharmony_ci            if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
188e1051a39Sopenharmony_ci                goto err;
189e1051a39Sopenharmony_ci            (void)sk_X509_NAME_ENTRY_set(entries, j, NULL);
190e1051a39Sopenharmony_ci        }
191e1051a39Sopenharmony_ci    }
192e1051a39Sopenharmony_ci    ret = x509_name_canon(nm.x);
193e1051a39Sopenharmony_ci    if (!ret)
194e1051a39Sopenharmony_ci        goto err;
195e1051a39Sopenharmony_ci    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
196e1051a39Sopenharmony_ci                                         local_sk_X509_NAME_ENTRY_free);
197e1051a39Sopenharmony_ci    nm.x->modified = 0;
198e1051a39Sopenharmony_ci    *val = nm.a;
199e1051a39Sopenharmony_ci    *in = p;
200e1051a39Sopenharmony_ci    return ret;
201e1051a39Sopenharmony_ci
202e1051a39Sopenharmony_ci err:
203e1051a39Sopenharmony_ci    if (nm.x != NULL)
204e1051a39Sopenharmony_ci        X509_NAME_free(nm.x);
205e1051a39Sopenharmony_ci    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
206e1051a39Sopenharmony_ci                                         local_sk_X509_NAME_ENTRY_pop_free);
207e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_ASN1, ERR_R_NESTED_ASN1_ERROR);
208e1051a39Sopenharmony_ci    return 0;
209e1051a39Sopenharmony_ci}
210e1051a39Sopenharmony_ci
211e1051a39Sopenharmony_cistatic int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out,
212e1051a39Sopenharmony_ci                            const ASN1_ITEM *it, int tag, int aclass)
213e1051a39Sopenharmony_ci{
214e1051a39Sopenharmony_ci    int ret;
215e1051a39Sopenharmony_ci    X509_NAME *a = (X509_NAME *)*val;
216e1051a39Sopenharmony_ci
217e1051a39Sopenharmony_ci    if (a->modified) {
218e1051a39Sopenharmony_ci        ret = x509_name_encode(a);
219e1051a39Sopenharmony_ci        if (ret < 0)
220e1051a39Sopenharmony_ci            return ret;
221e1051a39Sopenharmony_ci        ret = x509_name_canon(a);
222e1051a39Sopenharmony_ci        if (!ret)
223e1051a39Sopenharmony_ci            return -1;
224e1051a39Sopenharmony_ci    }
225e1051a39Sopenharmony_ci    ret = a->bytes->length;
226e1051a39Sopenharmony_ci    if (out != NULL) {
227e1051a39Sopenharmony_ci        memcpy(*out, a->bytes->data, ret);
228e1051a39Sopenharmony_ci        *out += ret;
229e1051a39Sopenharmony_ci    }
230e1051a39Sopenharmony_ci    return ret;
231e1051a39Sopenharmony_ci}
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_cistatic int x509_name_encode(X509_NAME *a)
234e1051a39Sopenharmony_ci{
235e1051a39Sopenharmony_ci    union {
236e1051a39Sopenharmony_ci        STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
237e1051a39Sopenharmony_ci        const ASN1_VALUE *a;
238e1051a39Sopenharmony_ci    } intname = {
239e1051a39Sopenharmony_ci        NULL
240e1051a39Sopenharmony_ci    };
241e1051a39Sopenharmony_ci    int len;
242e1051a39Sopenharmony_ci    unsigned char *p;
243e1051a39Sopenharmony_ci    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
244e1051a39Sopenharmony_ci    X509_NAME_ENTRY *entry;
245e1051a39Sopenharmony_ci    int i, set = -1;
246e1051a39Sopenharmony_ci
247e1051a39Sopenharmony_ci    intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
248e1051a39Sopenharmony_ci    if (!intname.s)
249e1051a39Sopenharmony_ci        goto memerr;
250e1051a39Sopenharmony_ci    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
251e1051a39Sopenharmony_ci        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
252e1051a39Sopenharmony_ci        if (entry->set != set) {
253e1051a39Sopenharmony_ci            entries = sk_X509_NAME_ENTRY_new_null();
254e1051a39Sopenharmony_ci            if (!entries)
255e1051a39Sopenharmony_ci                goto memerr;
256e1051a39Sopenharmony_ci            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) {
257e1051a39Sopenharmony_ci                sk_X509_NAME_ENTRY_free(entries);
258e1051a39Sopenharmony_ci                goto memerr;
259e1051a39Sopenharmony_ci            }
260e1051a39Sopenharmony_ci            set = entry->set;
261e1051a39Sopenharmony_ci        }
262e1051a39Sopenharmony_ci        if (!sk_X509_NAME_ENTRY_push(entries, entry))
263e1051a39Sopenharmony_ci            goto memerr;
264e1051a39Sopenharmony_ci    }
265e1051a39Sopenharmony_ci    len = ASN1_item_ex_i2d(&intname.a, NULL,
266e1051a39Sopenharmony_ci                           ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
267e1051a39Sopenharmony_ci    if (!BUF_MEM_grow(a->bytes, len))
268e1051a39Sopenharmony_ci        goto memerr;
269e1051a39Sopenharmony_ci    p = (unsigned char *)a->bytes->data;
270e1051a39Sopenharmony_ci    ASN1_item_ex_i2d(&intname.a,
271e1051a39Sopenharmony_ci                     &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
272e1051a39Sopenharmony_ci    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
273e1051a39Sopenharmony_ci                                         local_sk_X509_NAME_ENTRY_free);
274e1051a39Sopenharmony_ci    a->modified = 0;
275e1051a39Sopenharmony_ci    return len;
276e1051a39Sopenharmony_ci memerr:
277e1051a39Sopenharmony_ci    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
278e1051a39Sopenharmony_ci                                         local_sk_X509_NAME_ENTRY_free);
279e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
280e1051a39Sopenharmony_ci    return -1;
281e1051a39Sopenharmony_ci}
282e1051a39Sopenharmony_ci
283e1051a39Sopenharmony_cistatic int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval,
284e1051a39Sopenharmony_ci                              int indent,
285e1051a39Sopenharmony_ci                              const char *fname, const ASN1_PCTX *pctx)
286e1051a39Sopenharmony_ci{
287e1051a39Sopenharmony_ci    if (X509_NAME_print_ex(out, (const X509_NAME *)*pval,
288e1051a39Sopenharmony_ci                           indent, pctx->nm_flags) <= 0)
289e1051a39Sopenharmony_ci        return 0;
290e1051a39Sopenharmony_ci    return 2;
291e1051a39Sopenharmony_ci}
292e1051a39Sopenharmony_ci
293e1051a39Sopenharmony_ci/*
294e1051a39Sopenharmony_ci * This function generates the canonical encoding of the Name structure. In
295e1051a39Sopenharmony_ci * it all strings are converted to UTF8, leading, trailing and multiple
296e1051a39Sopenharmony_ci * spaces collapsed, converted to lower case and the leading SEQUENCE header
297e1051a39Sopenharmony_ci * removed. In future we could also normalize the UTF8 too. By doing this
298e1051a39Sopenharmony_ci * comparison of Name structures can be rapidly performed by just using
299e1051a39Sopenharmony_ci * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
300e1051a39Sopenharmony_ci * constraints of type dirName can also be checked with a simple memcmp().
301e1051a39Sopenharmony_ci * NOTE: For empty X509_NAME (NULL-DN), canon_enclen == 0 && canon_enc == NULL
302e1051a39Sopenharmony_ci */
303e1051a39Sopenharmony_ci
304e1051a39Sopenharmony_cistatic int x509_name_canon(X509_NAME *a)
305e1051a39Sopenharmony_ci{
306e1051a39Sopenharmony_ci    unsigned char *p;
307e1051a39Sopenharmony_ci    STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname;
308e1051a39Sopenharmony_ci    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
309e1051a39Sopenharmony_ci    X509_NAME_ENTRY *entry, *tmpentry = NULL;
310e1051a39Sopenharmony_ci    int i, set = -1, ret = 0, len;
311e1051a39Sopenharmony_ci
312e1051a39Sopenharmony_ci    OPENSSL_free(a->canon_enc);
313e1051a39Sopenharmony_ci    a->canon_enc = NULL;
314e1051a39Sopenharmony_ci    /* Special case: empty X509_NAME => null encoding */
315e1051a39Sopenharmony_ci    if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
316e1051a39Sopenharmony_ci        a->canon_enclen = 0;
317e1051a39Sopenharmony_ci        return 1;
318e1051a39Sopenharmony_ci    }
319e1051a39Sopenharmony_ci    intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
320e1051a39Sopenharmony_ci    if (intname == NULL) {
321e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
322e1051a39Sopenharmony_ci        goto err;
323e1051a39Sopenharmony_ci    }
324e1051a39Sopenharmony_ci    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
325e1051a39Sopenharmony_ci        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
326e1051a39Sopenharmony_ci        if (entry->set != set) {
327e1051a39Sopenharmony_ci            entries = sk_X509_NAME_ENTRY_new_null();
328e1051a39Sopenharmony_ci            if (entries == NULL)
329e1051a39Sopenharmony_ci                goto err;
330e1051a39Sopenharmony_ci            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
331e1051a39Sopenharmony_ci                sk_X509_NAME_ENTRY_free(entries);
332e1051a39Sopenharmony_ci                ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
333e1051a39Sopenharmony_ci                goto err;
334e1051a39Sopenharmony_ci            }
335e1051a39Sopenharmony_ci            set = entry->set;
336e1051a39Sopenharmony_ci        }
337e1051a39Sopenharmony_ci        tmpentry = X509_NAME_ENTRY_new();
338e1051a39Sopenharmony_ci        if (tmpentry == NULL) {
339e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
340e1051a39Sopenharmony_ci            goto err;
341e1051a39Sopenharmony_ci        }
342e1051a39Sopenharmony_ci        tmpentry->object = OBJ_dup(entry->object);
343e1051a39Sopenharmony_ci        if (tmpentry->object == NULL) {
344e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
345e1051a39Sopenharmony_ci            goto err;
346e1051a39Sopenharmony_ci        }
347e1051a39Sopenharmony_ci        if (!asn1_string_canon(tmpentry->value, entry->value))
348e1051a39Sopenharmony_ci            goto err;
349e1051a39Sopenharmony_ci        if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) {
350e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
351e1051a39Sopenharmony_ci            goto err;
352e1051a39Sopenharmony_ci        }
353e1051a39Sopenharmony_ci        tmpentry = NULL;
354e1051a39Sopenharmony_ci    }
355e1051a39Sopenharmony_ci
356e1051a39Sopenharmony_ci    /* Finally generate encoding */
357e1051a39Sopenharmony_ci    len = i2d_name_canon(intname, NULL);
358e1051a39Sopenharmony_ci    if (len < 0)
359e1051a39Sopenharmony_ci        goto err;
360e1051a39Sopenharmony_ci    a->canon_enclen = len;
361e1051a39Sopenharmony_ci
362e1051a39Sopenharmony_ci    p = OPENSSL_malloc(a->canon_enclen);
363e1051a39Sopenharmony_ci    if (p == NULL) {
364e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE);
365e1051a39Sopenharmony_ci        goto err;
366e1051a39Sopenharmony_ci    }
367e1051a39Sopenharmony_ci
368e1051a39Sopenharmony_ci    a->canon_enc = p;
369e1051a39Sopenharmony_ci
370e1051a39Sopenharmony_ci    i2d_name_canon(intname, &p);
371e1051a39Sopenharmony_ci
372e1051a39Sopenharmony_ci    ret = 1;
373e1051a39Sopenharmony_ci
374e1051a39Sopenharmony_ci err:
375e1051a39Sopenharmony_ci    X509_NAME_ENTRY_free(tmpentry);
376e1051a39Sopenharmony_ci    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
377e1051a39Sopenharmony_ci                                         local_sk_X509_NAME_ENTRY_pop_free);
378e1051a39Sopenharmony_ci    return ret;
379e1051a39Sopenharmony_ci}
380e1051a39Sopenharmony_ci
381e1051a39Sopenharmony_ci/* Bitmap of all the types of string that will be canonicalized. */
382e1051a39Sopenharmony_ci
383e1051a39Sopenharmony_ci#define ASN1_MASK_CANON \
384e1051a39Sopenharmony_ci        (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
385e1051a39Sopenharmony_ci        | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
386e1051a39Sopenharmony_ci        | B_ASN1_VISIBLESTRING)
387e1051a39Sopenharmony_ci
388e1051a39Sopenharmony_cistatic int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in)
389e1051a39Sopenharmony_ci{
390e1051a39Sopenharmony_ci    unsigned char *to, *from;
391e1051a39Sopenharmony_ci    int len, i;
392e1051a39Sopenharmony_ci
393e1051a39Sopenharmony_ci    /* If type not in bitmask just copy string across */
394e1051a39Sopenharmony_ci    if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
395e1051a39Sopenharmony_ci        if (!ASN1_STRING_copy(out, in))
396e1051a39Sopenharmony_ci            return 0;
397e1051a39Sopenharmony_ci        return 1;
398e1051a39Sopenharmony_ci    }
399e1051a39Sopenharmony_ci
400e1051a39Sopenharmony_ci    out->type = V_ASN1_UTF8STRING;
401e1051a39Sopenharmony_ci    out->length = ASN1_STRING_to_UTF8(&out->data, in);
402e1051a39Sopenharmony_ci    if (out->length == -1)
403e1051a39Sopenharmony_ci        return 0;
404e1051a39Sopenharmony_ci
405e1051a39Sopenharmony_ci    to = out->data;
406e1051a39Sopenharmony_ci    from = to;
407e1051a39Sopenharmony_ci
408e1051a39Sopenharmony_ci    len = out->length;
409e1051a39Sopenharmony_ci
410e1051a39Sopenharmony_ci    /*
411e1051a39Sopenharmony_ci     * Convert string in place to canonical form. Ultimately we may need to
412e1051a39Sopenharmony_ci     * handle a wider range of characters but for now ignore anything with
413e1051a39Sopenharmony_ci     * MSB set and rely on the ossl_isspace() to fail on bad characters without
414e1051a39Sopenharmony_ci     * needing isascii or range checks as well.
415e1051a39Sopenharmony_ci     */
416e1051a39Sopenharmony_ci
417e1051a39Sopenharmony_ci    /* Ignore leading spaces */
418e1051a39Sopenharmony_ci    while (len > 0 && ossl_isspace(*from)) {
419e1051a39Sopenharmony_ci        from++;
420e1051a39Sopenharmony_ci        len--;
421e1051a39Sopenharmony_ci    }
422e1051a39Sopenharmony_ci
423e1051a39Sopenharmony_ci    to = from + len;
424e1051a39Sopenharmony_ci
425e1051a39Sopenharmony_ci    /* Ignore trailing spaces */
426e1051a39Sopenharmony_ci    while (len > 0 && ossl_isspace(to[-1])) {
427e1051a39Sopenharmony_ci        to--;
428e1051a39Sopenharmony_ci        len--;
429e1051a39Sopenharmony_ci    }
430e1051a39Sopenharmony_ci
431e1051a39Sopenharmony_ci    to = out->data;
432e1051a39Sopenharmony_ci
433e1051a39Sopenharmony_ci    i = 0;
434e1051a39Sopenharmony_ci    while (i < len) {
435e1051a39Sopenharmony_ci        /* If not ASCII set just copy across */
436e1051a39Sopenharmony_ci        if (!ossl_isascii(*from)) {
437e1051a39Sopenharmony_ci            *to++ = *from++;
438e1051a39Sopenharmony_ci            i++;
439e1051a39Sopenharmony_ci        }
440e1051a39Sopenharmony_ci        /* Collapse multiple spaces */
441e1051a39Sopenharmony_ci        else if (ossl_isspace(*from)) {
442e1051a39Sopenharmony_ci            /* Copy one space across */
443e1051a39Sopenharmony_ci            *to++ = ' ';
444e1051a39Sopenharmony_ci            /*
445e1051a39Sopenharmony_ci             * Ignore subsequent spaces. Note: don't need to check len here
446e1051a39Sopenharmony_ci             * because we know the last character is a non-space so we can't
447e1051a39Sopenharmony_ci             * overflow.
448e1051a39Sopenharmony_ci             */
449e1051a39Sopenharmony_ci            do {
450e1051a39Sopenharmony_ci                from++;
451e1051a39Sopenharmony_ci                i++;
452e1051a39Sopenharmony_ci            }
453e1051a39Sopenharmony_ci            while (ossl_isspace(*from));
454e1051a39Sopenharmony_ci        } else {
455e1051a39Sopenharmony_ci            *to++ = ossl_tolower(*from);
456e1051a39Sopenharmony_ci            from++;
457e1051a39Sopenharmony_ci            i++;
458e1051a39Sopenharmony_ci        }
459e1051a39Sopenharmony_ci    }
460e1051a39Sopenharmony_ci
461e1051a39Sopenharmony_ci    out->length = to - out->data;
462e1051a39Sopenharmony_ci
463e1051a39Sopenharmony_ci    return 1;
464e1051a39Sopenharmony_ci
465e1051a39Sopenharmony_ci}
466e1051a39Sopenharmony_ci
467e1051a39Sopenharmony_cistatic int i2d_name_canon(const STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
468e1051a39Sopenharmony_ci                          unsigned char **in)
469e1051a39Sopenharmony_ci{
470e1051a39Sopenharmony_ci    int i, len, ltmp;
471e1051a39Sopenharmony_ci    const ASN1_VALUE *v;
472e1051a39Sopenharmony_ci    STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
473e1051a39Sopenharmony_ci
474e1051a39Sopenharmony_ci    len = 0;
475e1051a39Sopenharmony_ci    for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
476e1051a39Sopenharmony_ci        v = sk_ASN1_VALUE_value(intname, i);
477e1051a39Sopenharmony_ci        ltmp = ASN1_item_ex_i2d(&v, in,
478e1051a39Sopenharmony_ci                                ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
479e1051a39Sopenharmony_ci        if (ltmp < 0)
480e1051a39Sopenharmony_ci            return ltmp;
481e1051a39Sopenharmony_ci        len += ltmp;
482e1051a39Sopenharmony_ci    }
483e1051a39Sopenharmony_ci    return len;
484e1051a39Sopenharmony_ci}
485e1051a39Sopenharmony_ci
486e1051a39Sopenharmony_ciint X509_NAME_set(X509_NAME **xn, const X509_NAME *name)
487e1051a39Sopenharmony_ci{
488e1051a39Sopenharmony_ci    X509_NAME *name_copy;
489e1051a39Sopenharmony_ci
490e1051a39Sopenharmony_ci    if (*xn == name)
491e1051a39Sopenharmony_ci        return *xn != NULL;
492e1051a39Sopenharmony_ci    if ((name_copy = X509_NAME_dup(name)) == NULL)
493e1051a39Sopenharmony_ci        return 0;
494e1051a39Sopenharmony_ci    X509_NAME_free(*xn);
495e1051a39Sopenharmony_ci    *xn = name_copy;
496e1051a39Sopenharmony_ci    return 1;
497e1051a39Sopenharmony_ci}
498e1051a39Sopenharmony_ci
499e1051a39Sopenharmony_ciint X509_NAME_print(BIO *bp, const X509_NAME *name, int obase)
500e1051a39Sopenharmony_ci{
501e1051a39Sopenharmony_ci    char *s, *c, *b;
502e1051a39Sopenharmony_ci    int i;
503e1051a39Sopenharmony_ci
504e1051a39Sopenharmony_ci    b = X509_NAME_oneline(name, NULL, 0);
505e1051a39Sopenharmony_ci    if (b == NULL)
506e1051a39Sopenharmony_ci        return 0;
507e1051a39Sopenharmony_ci    if (*b == '\0') {
508e1051a39Sopenharmony_ci        OPENSSL_free(b);
509e1051a39Sopenharmony_ci        return 1;
510e1051a39Sopenharmony_ci    }
511e1051a39Sopenharmony_ci    s = b + 1;                  /* skip the first slash */
512e1051a39Sopenharmony_ci
513e1051a39Sopenharmony_ci    c = s;
514e1051a39Sopenharmony_ci    for (;;) {
515e1051a39Sopenharmony_ci        if (((*s == '/') &&
516e1051a39Sopenharmony_ci             (ossl_isupper(s[1]) && ((s[2] == '=') ||
517e1051a39Sopenharmony_ci                                (ossl_isupper(s[2]) && (s[3] == '='))
518e1051a39Sopenharmony_ci              ))) || (*s == '\0'))
519e1051a39Sopenharmony_ci        {
520e1051a39Sopenharmony_ci            i = s - c;
521e1051a39Sopenharmony_ci            if (BIO_write(bp, c, i) != i)
522e1051a39Sopenharmony_ci                goto err;
523e1051a39Sopenharmony_ci            c = s + 1;          /* skip following slash */
524e1051a39Sopenharmony_ci            if (*s != '\0') {
525e1051a39Sopenharmony_ci                if (BIO_write(bp, ", ", 2) != 2)
526e1051a39Sopenharmony_ci                    goto err;
527e1051a39Sopenharmony_ci            }
528e1051a39Sopenharmony_ci        }
529e1051a39Sopenharmony_ci        if (*s == '\0')
530e1051a39Sopenharmony_ci            break;
531e1051a39Sopenharmony_ci        s++;
532e1051a39Sopenharmony_ci    }
533e1051a39Sopenharmony_ci
534e1051a39Sopenharmony_ci    OPENSSL_free(b);
535e1051a39Sopenharmony_ci    return 1;
536e1051a39Sopenharmony_ci err:
537e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB);
538e1051a39Sopenharmony_ci    OPENSSL_free(b);
539e1051a39Sopenharmony_ci    return 0;
540e1051a39Sopenharmony_ci}
541e1051a39Sopenharmony_ci
542e1051a39Sopenharmony_ciint X509_NAME_get0_der(const X509_NAME *nm, const unsigned char **pder,
543e1051a39Sopenharmony_ci                       size_t *pderlen)
544e1051a39Sopenharmony_ci{
545e1051a39Sopenharmony_ci    /* Make sure encoding is valid */
546e1051a39Sopenharmony_ci    if (i2d_X509_NAME(nm, NULL) <= 0)
547e1051a39Sopenharmony_ci        return 0;
548e1051a39Sopenharmony_ci    if (pder != NULL)
549e1051a39Sopenharmony_ci        *pder = (unsigned char *)nm->bytes->data;
550e1051a39Sopenharmony_ci    if (pderlen != NULL)
551e1051a39Sopenharmony_ci        *pderlen = nm->bytes->length;
552e1051a39Sopenharmony_ci    return 1;
553e1051a39Sopenharmony_ci}
554