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.
8296465Sdelphij *
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).
15296465Sdelphij *
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.
22296465Sdelphij *
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 :-).
37296465Sdelphij * 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)"
40296465Sdelphij *
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.
52296465Sdelphij *
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>
6055714Skris#include "cryptlib.h"
61109998Smarkm#include <openssl/asn1t.h>
6255714Skris#include <openssl/x509.h>
6355714Skris
64296465Sdelphijstatic int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
65296465Sdelphij                            long len, const ASN1_ITEM *it, int tag,
66296465Sdelphij                            int aclass, char opt, ASN1_TLC *ctx);
6755714Skris
68296465Sdelphijstatic int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
69296465Sdelphij                            const ASN1_ITEM *it, int tag, int aclass);
70109998Smarkmstatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
71109998Smarkmstatic void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
7255714Skris
73109998Smarkmstatic int x509_name_encode(X509_NAME *a);
7455714Skris
75109998SmarkmASN1_SEQUENCE(X509_NAME_ENTRY) = {
76296465Sdelphij        ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
77296465Sdelphij        ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
78109998Smarkm} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
7955714Skris
80109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
81109998SmarkmIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
8255714Skris
83296465Sdelphij/*
84296465Sdelphij * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
85296465Sdelphij * declare two template wrappers for this
86109998Smarkm */
8755714Skris
88109998SmarkmASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
89296465Sdelphij        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
90109998SmarkmASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
9155714Skris
92109998SmarkmASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
93296465Sdelphij        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
94109998SmarkmASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
9555714Skris
96296465Sdelphij/*
97296465Sdelphij * Normally that's where it would end: we'd have two nested STACK structures
98109998Smarkm * representing the ASN1. Unfortunately X509_NAME uses a completely different
99296465Sdelphij * form and caches encodings so we have to process the internal form and
100296465Sdelphij * convert to the external form.
101109998Smarkm */
10255714Skris
103109998Smarkmconst ASN1_EXTERN_FUNCS x509_name_ff = {
104296465Sdelphij    NULL,
105296465Sdelphij    x509_name_ex_new,
106296465Sdelphij    x509_name_ex_free,
107296465Sdelphij    0,                          /* Default clear behaviour is OK */
108296465Sdelphij    x509_name_ex_d2i,
109296465Sdelphij    x509_name_ex_i2d
110109998Smarkm};
11155714Skris
112296465SdelphijIMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
11355714Skris
114109998SmarkmIMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
115296465Sdelphij
116109998SmarkmIMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
11755714Skris
118109998Smarkmstatic int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
119109998Smarkm{
120296465Sdelphij    X509_NAME *ret = NULL;
121296465Sdelphij    ret = OPENSSL_malloc(sizeof(X509_NAME));
122296465Sdelphij    if (!ret)
123296465Sdelphij        goto memerr;
124296465Sdelphij    if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
125296465Sdelphij        goto memerr;
126296465Sdelphij    if ((ret->bytes = BUF_MEM_new()) == NULL)
127296465Sdelphij        goto memerr;
128296465Sdelphij    ret->modified = 1;
129296465Sdelphij    *val = (ASN1_VALUE *)ret;
130296465Sdelphij    return 1;
131109998Smarkm
132109998Smarkm memerr:
133296465Sdelphij    ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
134296465Sdelphij    if (ret) {
135296465Sdelphij        if (ret->entries)
136296465Sdelphij            sk_X509_NAME_ENTRY_free(ret->entries);
137296465Sdelphij        OPENSSL_free(ret);
138296465Sdelphij    }
139296465Sdelphij    return 0;
140109998Smarkm}
14155714Skris
142109998Smarkmstatic void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
143109998Smarkm{
144296465Sdelphij    X509_NAME *a;
145296465Sdelphij    if (!pval || !*pval)
146296465Sdelphij        return;
147296465Sdelphij    a = (X509_NAME *)*pval;
14855714Skris
149296465Sdelphij    BUF_MEM_free(a->bytes);
150296465Sdelphij    sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
151296465Sdelphij    OPENSSL_free(a);
152296465Sdelphij    *pval = NULL;
153109998Smarkm}
15455714Skris
155296465Sdelphij/*
156296465Sdelphij * Used with sk_pop_free() to free up the internal representation. NB: we
157296465Sdelphij * only free the STACK and not its contents because it is already present in
158296465Sdelphij * the X509_NAME structure.
159109998Smarkm */
16055714Skris
161109998Smarkmstatic void sk_internal_free(void *a)
162109998Smarkm{
163296465Sdelphij    sk_free(a);
164109998Smarkm}
16555714Skris
166296465Sdelphijstatic int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
167296465Sdelphij                            long len, const ASN1_ITEM *it, int tag,
168296465Sdelphij                            int aclass, char opt, ASN1_TLC *ctx)
169109998Smarkm{
170296465Sdelphij    const unsigned char *p = *in, *q;
171296465Sdelphij    union {
172296465Sdelphij        STACK *s;
173296465Sdelphij        ASN1_VALUE *a;
174296465Sdelphij    } intname = {
175296465Sdelphij        NULL
176296465Sdelphij    };
177296465Sdelphij    union {
178296465Sdelphij        X509_NAME *x;
179296465Sdelphij        ASN1_VALUE *a;
180296465Sdelphij    } nm = {
181296465Sdelphij        NULL
182296465Sdelphij    };
183296465Sdelphij    int i, j, ret;
184296465Sdelphij    STACK_OF(X509_NAME_ENTRY) *entries;
185296465Sdelphij    X509_NAME_ENTRY *entry;
186296465Sdelphij    q = p;
18755714Skris
188296465Sdelphij    /* Get internal representation of Name */
189296465Sdelphij    ret = ASN1_item_ex_d2i(&intname.a,
190296465Sdelphij                           &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
191296465Sdelphij                           tag, aclass, opt, ctx);
19255714Skris
193296465Sdelphij    if (ret <= 0)
194296465Sdelphij        return ret;
195109998Smarkm
196296465Sdelphij    if (*val)
197296465Sdelphij        x509_name_ex_free(val, NULL);
198296465Sdelphij    if (!x509_name_ex_new(&nm.a, NULL))
199296465Sdelphij        goto err;
200296465Sdelphij    /* We've decoded it: now cache encoding */
201296465Sdelphij    if (!BUF_MEM_grow(nm.x->bytes, p - q))
202296465Sdelphij        goto err;
203296465Sdelphij    memcpy(nm.x->bytes->data, q, p - q);
204296465Sdelphij
205296465Sdelphij    /* Convert internal representation to X509_NAME structure */
206296465Sdelphij    for (i = 0; i < sk_num(intname.s); i++) {
207296465Sdelphij        entries = (STACK_OF(X509_NAME_ENTRY) *)sk_value(intname.s, i);
208296465Sdelphij        for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
209296465Sdelphij            entry = sk_X509_NAME_ENTRY_value(entries, j);
210296465Sdelphij            entry->set = i;
211296465Sdelphij            if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
212296465Sdelphij                goto err;
213296465Sdelphij        }
214296465Sdelphij        sk_X509_NAME_ENTRY_free(entries);
215296465Sdelphij    }
216296465Sdelphij    sk_free(intname.s);
217296465Sdelphij    nm.x->modified = 0;
218296465Sdelphij    *val = nm.a;
219296465Sdelphij    *in = p;
220296465Sdelphij    return ret;
221296465Sdelphij err:
222296465Sdelphij    if (nm.x != NULL)
223296465Sdelphij        X509_NAME_free(nm.x);
224296465Sdelphij    ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
225296465Sdelphij    return 0;
226109998Smarkm}
22755714Skris
228296465Sdelphijstatic int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
229296465Sdelphij                            const ASN1_ITEM *it, int tag, int aclass)
230109998Smarkm{
231296465Sdelphij    int ret;
232296465Sdelphij    X509_NAME *a = (X509_NAME *)*val;
233296465Sdelphij    if (a->modified) {
234296465Sdelphij        ret = x509_name_encode((X509_NAME *)a);
235296465Sdelphij        if (ret < 0)
236296465Sdelphij            return ret;
237296465Sdelphij    }
238296465Sdelphij    ret = a->bytes->length;
239296465Sdelphij    if (out != NULL) {
240296465Sdelphij        memcpy(*out, a->bytes->data, ret);
241296465Sdelphij        *out += ret;
242296465Sdelphij    }
243296465Sdelphij    return ret;
244109998Smarkm}
24555714Skris
246109998Smarkmstatic int x509_name_encode(X509_NAME *a)
247109998Smarkm{
248296465Sdelphij    union {
249296465Sdelphij        STACK *s;
250296465Sdelphij        ASN1_VALUE *a;
251296465Sdelphij    } intname = {
252296465Sdelphij        NULL
253296465Sdelphij    };
254296465Sdelphij    int len;
255296465Sdelphij    unsigned char *p;
256296465Sdelphij    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
257296465Sdelphij    X509_NAME_ENTRY *entry;
258296465Sdelphij    int i, set = -1;
259296465Sdelphij    intname.s = sk_new_null();
260296465Sdelphij    if (!intname.s)
261296465Sdelphij        goto memerr;
262296465Sdelphij    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
263296465Sdelphij        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
264296465Sdelphij        if (entry->set != set) {
265296465Sdelphij            entries = sk_X509_NAME_ENTRY_new_null();
266296465Sdelphij            if (!entries)
267296465Sdelphij                goto memerr;
268296465Sdelphij            if (!sk_push(intname.s, (char *)entries))
269296465Sdelphij                goto memerr;
270296465Sdelphij            set = entry->set;
271296465Sdelphij        }
272296465Sdelphij        if (!sk_X509_NAME_ENTRY_push(entries, entry))
273296465Sdelphij            goto memerr;
274296465Sdelphij    }
275296465Sdelphij    len = ASN1_item_ex_i2d(&intname.a, NULL,
276296465Sdelphij                           ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
277296465Sdelphij    if (!BUF_MEM_grow(a->bytes, len))
278296465Sdelphij        goto memerr;
279296465Sdelphij    p = (unsigned char *)a->bytes->data;
280296465Sdelphij    ASN1_item_ex_i2d(&intname.a,
281296465Sdelphij                     &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
282296465Sdelphij    sk_pop_free(intname.s, sk_internal_free);
283296465Sdelphij    a->modified = 0;
284296465Sdelphij    return len;
285296465Sdelphij memerr:
286296465Sdelphij    sk_pop_free(intname.s, sk_internal_free);
287296465Sdelphij    ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
288296465Sdelphij    return -1;
289109998Smarkm}
29055714Skris
29155714Skrisint X509_NAME_set(X509_NAME **xn, X509_NAME *name)
292296465Sdelphij{
293296465Sdelphij    X509_NAME *in;
29455714Skris
295296465Sdelphij    if (!xn || !name)
296296465Sdelphij        return (0);
29755714Skris
298296465Sdelphij    if (*xn != name) {
299296465Sdelphij        in = X509_NAME_dup(name);
300296465Sdelphij        if (in != NULL) {
301296465Sdelphij            X509_NAME_free(*xn);
302296465Sdelphij            *xn = in;
303296465Sdelphij        }
304296465Sdelphij    }
305296465Sdelphij    return (*xn != NULL);
306296465Sdelphij}
307296465Sdelphij
30855714SkrisIMPLEMENT_STACK_OF(X509_NAME_ENTRY)
309296465Sdelphij
31055714SkrisIMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
311